FreeSwitch系列之内存管理

1.sofia-sip库的内存管理

home-based 内存管理机制,在需要分配许多内存块的情况下非常有用。分配器是通过分配中心保存各个分配内存块的引用来实现的。当分配中心释放,所有它保持引用的内存块都会被释放。

为一个给定任务分配大量的内存块时基于home的内存管理将非常高效。分配将通过home内存来执行,home内存保留着每个分配内存块的地址。当home内存被释放时,它也将释放那些它跟踪的内存块。这大大简化了应用代码逻辑,不再需要维护每块分配的内存空间,不需要保留他们的地址也不再需要一个个单独释放。

 

核心代码剖析

核心数据结构

/** Memory home structure */
struct su_home_s {
  int         suh_size;
  su_block_t *suh_blocks;
  su_alock_t *suh_lock;
};


struct su_block_s {
  su_home_t  *sub_parent;	/**< Parent home */
  char       *sub_preload;	/**< Preload area */
  su_home_stat_t *sub_stats;	/**< Statistics.. */
  void      (*sub_destructor)(void *); /**< Destructor function */
  size_t      sub_ref;		/**< Reference count */
#define REF_MAX SIZE_MAX
  size_t      sub_used;		/**< Number of blocks allocated */
  size_t      sub_n;		/**< Size of hash table  */

  unsigned    sub_prsize:16;	/**< Preload size */
  unsigned    sub_prused:16;	/**< Used from preload */
  unsigned    sub_hauto:1;      /**< "Home" is not from malloc */
  unsigned    sub_auto:1;	/**< struct su_block_s is not from malloc */
  unsigned    sub_preauto:1;	/**< Preload is not from malloc */
  unsigned    sub_auto_all:1;	/**< Everything is from stack! */
  unsigned :0;

  su_alloc_t  sub_nodes[SUB_N];	/**< Pointers to data/lower blocks */
};

typedef struct {
  unsigned sua_size:SIZEBITS;	/**< Size of the block */
  unsigned sua_home:1;		/**< Is this another home? */
  unsigned :0;
  void    *sua_data;		/**< Data pointer */
} su_alloc_t;


从结构体类型来看,整个Home based memory management包括三个层级。最上层是su_home_s,中间一层是su_block_s,最下那层是su_alloc_t。su_home_s结构体保留一个指向su_block_s结构体的指针,su_block_s包含一个su_alloc_t类型的数组。

使用方法

1、先申明一个包含有su_home_s结构体对象的结构体,类似于这样

struct context {  su_home_t ctx_home[1];  other_t  *ctx_stuff;  ...}

context结构体内第一个就是su_home_s结构体对象。然后context结构体内包含了其他的对象。要求就是必须确保context结构体内第一个对象一定时su_home_s对象。

2、然后就是调用创建函数创建、初始化context结构体对象。

struct context *ctx = su_home_new(sizeof (struct context));

3、接着使用su_zalloc函数处理内存分配事宜。

zeroblock = su_zalloc(ctx->ctx_home, sizeof (*zeroblock));

4、调用su_home_deinit(ctx->ctx_home)释放内存。

2.APR内存池

Apache中的内存分配的基本结构都是资源池,包括线程池,套接字池等等。内存池通常是一块很大的内存空间,一次性被分配成功,然后需要的时候直接去池中取,而不需要重新分配,这样避免的频繁的malloc操作,而且另一方面,即时内存的使用者忘记释放内存或者根本就不想分配,那么这些内存也不会丢失,它们仍然保存在内存池中,当内存池被销毁的时候这些内存将自动的被销毁。

使用方法

1、创建一个内存池。

switch_core_new_memory_pool(&usepool);

2、从内存池中分配。

session = switch_core_alloc(usepool, sizeof(*session));

3、销毁内存池,回收内存。

switch_core_destroy_memory_pool(usepool);

内存回收剖析

在Freeswitch使用apr内存池中,在调用

switch_core_perform_destroy_memory_pool后,并没有马上回收内存,而是放到了memory_manager.pool_queue的队列里面,再由单独的一个线程,从这个队列里面取出指针进行销毁。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值