个人理解
freeswitch目前使用apr来管理所有的内存,
在这套方案中,核心概念是池的概念。Apache中的内存分配的基本结构都是资源池,包括线程池,套接字池等等。内存池通常是一块很大的内存空间,一次性被分配成功,然后需要的时候直接去池中取,而不需要重新分配,这样避免的频繁的malloc操作,而且另一方面,即时内存的使用者忘记释放内存或者根本就不想分配,那么这些内存也不会丢失,它们仍然保存在内存池中,当内存池被销毁的时候这些内存将自动的被销毁。
个人理解:
- 系统启动的时候, 分配一个大内存池
- 当函数开始处理的时候, 根据需要创建子内存池
- 在子内存池上面分配内存,存储字符串等资源,使用指针引用这些资源
- 函数处理完毕, 释放整个子内存池,其实就是将子内存池占用的空间,还给那个大池子。
此处是将整个子内存池释放, 即使里面有什么不合理的东西, 也不会造成内存泄露。
完整代码示例
switch_memory_pool_t *pool;
struct bg_job *job;
switch_core_new_memory_pool(&pool);
job = switch_core_alloc(pool, sizeof(*job));
...
基于job做各种处理。。。
...
apr_pool_destroy(*pool);
pool = NULL;
申请内存池
freeswitch使用switch_core_new_memory_pool来申请内存池,
具体代码如下:
switch_memory_pool_t *pool;
struct bg_job *job;
switch_core_new_memory_pool(&pool);
switch_core_new_memory_pool在定义中明确说明是从核心的主内存池中,创建一个子内存池返回。
/*!
\brief Create a new sub memory pool from the core's master pool
\return SWITCH_STATUS_SUCCESS on success
*/
#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从池中分配内存,具体如下:
switch_memory_pool_t *pool;
struct bg_job *job;
switch_core_new_memory_pool(&pool);
job = switch_core_alloc(pool, sizeof(*job));
switch_core_alloc是一个宏,具体指向的是switch_core_perform_alloc,如下:
#define switch_core_alloc(_pool, _mem) switch_core_perform_alloc(_pool, _mem, __FILE__, __SWITCH_FUNC__, __LINE__)
switch_core_perform_alloc的逻辑代码如下(省略了不相干以及看不懂的代码):
SWITCH_DECLARE(void *) switch_core_perform_alloc(switch_memory_pool_t *pool, switch_size_t memory, const char *file, const char *func, int line)
{
void *ptr = NULL;
...
ptr = apr_palloc(pool, memory);
switch_assert(ptr != NULL);
//将分配的内存块全部用0初始化
memset(ptr, 0, memory);
...
return ptr;
}
使用apr库里面的apr_palloc函数,从内存池中分配一个内存,然后使用memset初始化.
释放内存
switch_core_destroy_memory_pool(&pool);
pool = NULL;
switch_core_destroy_memory_pool同样是一个宏, 指向switch_core_perform_destroy_memory_pool。
switch_core_perform_destroy_memory_pool的作用只要一个,就是调用apr_pool_destroy(*pool)释放子内存池到总的大池子里。
/*!
\brief Returns a subpool back to the main pool
\return SWITCH_STATUS_SUCCESS on success
*/
#define switch_core_destroy_memory_pool(p) switch_core_perform_destroy_memory_pool(p, __FILE__, __SWITCH_FUNC__, __LINE__)