apr_pool_destroy函数与apr_pool_clear函数前部分工作非常的相似,对于给定内存池,它的所有的子内存池将被完全释放,记住不是归还给分配子,而是彻底归还给操作系统。两者的区别是对给定当前内存池节点的处理。apr_pool_clear并不会释放内存中的任何内存,而apr_pool_destroy则正好相反:
if (pool->parent) {
if ((*pool->ref = pool->sibling) != NULL)
pool->sibling->ref = pool->ref;
}
allocator = pool->allocator;
active = pool->self;
*active->ref = NULL;
allocator_free(allocator, active);
if (apr_allocator_owner_get(allocator) == pool) {
apr_allocator_destroy(allocator);
}
如果当前内存池存在父内存池,那么函数将自己从父内存池的孩子链表中脱离开来。然后调用apr_allocator_free将内存归还给关联分配子。如果被释放的内存池正好是分配子的属主,那么属于该内存池的所有的分配子也应该被完全的销毁返回给操作系统。因此函数将调用apr_allocator_owner_get(allocator)函数进行判断。
在销毁分配子的时候有一点需要注意的是,由于需要判断当前分配子的是否属于当前的内存池,而内存池结构在检测之前已经被释放,因此,在释放内存池之前必须将其记录下来以备使用。如果缺少了这一步,allocator可能造成内存泄漏。
现在我们看一下run_cleanups函数,该函数很简单,无非就是遍历cleanup_t链表,并逐一调用它们的plain_cleanup_fn函数。
static void run_cleanups(cleanup_t **cref)
{
cleanup_t *c = *cref;
while (c) {
*cref = c->next;
(*c->plain_cleanup_fn)((void *)c->data);
c = *cref;
}
}
关于作者
张中庆,目前主要的研究方向是嵌入式浏览器,移动中间件以及大规模服务器设计。目前正在进行Apache的源代码分析,计划出版《Apache源代码全景分析》上下册。Apache系列文章为本书的草案部分,对Apache感兴趣的朋友可以通过flydish at sina.com.cn与之联系!
关于作者
张中庆,目前主要的研究方向是嵌入式浏览器,移动中间件以及大规模服务器设计。目前正在进行Apache的源代码分析,计划出版《Apache源代码全景分析》上下册。Apache系列文章为本书的草案部分,对Apache感兴趣的朋友可以通过flydish at sina.com.cn与之联系!
本文关键:Apache内存池内幕(7)