个人理解

freeswitch目前使用apr来管理所有的内存,

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

个人理解:

  1. 系统启动的时候, 分配一个大内存池
  2. 当函数开始处理的时候, 根据需要创建子内存池
  3. 在子内存池上面分配内存,存储字符串等资源,使用指针引用这些资源
  4. 函数处理完毕, 释放整个子内存池,其实就是将子内存池占用的空间,还给那个大池子。

此处是将整个子内存池释放, 即使里面有什么不合理的东西, 也不会造成内存泄露。

完整代码示例

  1. switch_memory_pool_t *pool;
  2. struct bg_job *job;
  3. switch_core_new_memory_pool(&pool);
  4. job = switch_core_alloc(pool, sizeof(*job));
  5. ...
  6. 基于job做各种处理。。。
  7. ...
  8. apr_pool_destroy(*pool);
  9. pool = NULL;

申请内存池

freeswitch使用switch_core_new_memory_pool来申请内存池,
具体代码如下:

  1. switch_memory_pool_t *pool;
  2. struct bg_job *job;
  3. switch_core_new_memory_pool(&pool);

switch_core_new_memory_pool在定义中明确说明是从核心的主内存池中,创建一个子内存池返回。

  1. /*!
  2. \brief Create a new sub memory pool from the core's master pool
  3. \return SWITCH_STATUS_SUCCESS on success
  4. */
  5. #define switch_core_new_memory_pool(p) switch_core_perform_new_memory_pool(p, __FILE__, __SWITCH_FUNC__, __LINE__)

至于具体的switch_core_perform_new_memory_pool是怎么实现的,目前还没能力关心到这一层,先跳过。

分配内存

内存池申请好了之后,再使用switch_core_alloc从池中分配内存,具体如下:

  1. switch_memory_pool_t *pool;
  2. struct bg_job *job;
  3. switch_core_new_memory_pool(&pool);
  4. job = switch_core_alloc(pool, sizeof(*job));

switch_core_alloc是一个宏,具体指向的是switch_core_perform_alloc,如下:

  1. #define switch_core_alloc(_pool, _mem) switch_core_perform_alloc(_pool, _mem, __FILE__, __SWITCH_FUNC__, __LINE__)

switch_core_perform_alloc的逻辑代码如下(省略了不相干以及看不懂的代码):

  1. SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, switch_size_t memory, const char *file, const char *func, int line)
  2. {
  3. void *ptr = NULL;
  4. ...
  5. ptr = apr_palloc(pool, memory);
  6. switch_assert(ptr != NULL);
  7. //将分配的内存块全部用0初始化
  8. memset(ptr, 0, memory);
  9. ...
  10. return ptr;
  11. }

使用apr库里面的apr_palloc函数,从内存池中分配一个内存,然后使用memset初始化.

释放内存

  1. switch_core_destroy_memory_pool(&pool);
  2. pool = NULL;

switch_core_destroy_memory_pool同样是一个宏, 指向switch_core_perform_destroy_memory_pool。
switch_core_perform_destroy_memory_pool的作用只要一个,就是调用apr_pool_destroy(*pool)释放子内存池到总的大池子里。

  1. /*!
  2. \brief Returns a subpool back to the main pool
  3. \return SWITCH_STATUS_SUCCESS on success
  4. */
  5. #define switch_core_destroy_memory_pool(p) switch_core_perform_destroy_memory_pool(p, __FILE__, __SWITCH_FUNC__, __LINE__)