apr内存池阅读笔记-内存池的释放与销毁

如有错误和建议欢迎留言。

apr_pool_clear与销毁接口的实现差不多,少了内存池的清理与分配器销毁的代码。

APR_DECLARE(void) apr_pool_destroy(apr_pool_t *pool)
{
    apr_memnode_t *active;
    apr_allocator_t *allocator;

    /* 清理函数 */
    run_cleanups(&pool->pre_cleanups);
    pool->pre_cleanups = NULL;

    /*销毁子内存池*/
    while (pool->child)
        apr_pool_destroy(pool->child);

    /* 清理函数 */
    run_cleanups(&pool->cleanups);

    /* Free subprocesses */
    free_proc_chain(pool->subprocesses);

    //将内存池从兄弟链表中删除
    if (pool->parent) {
#if APR_HAS_THREADS
        apr_thread_mutex_t *mutex;

        if ((mutex = apr_allocator_mutex_get(pool->parent->allocator)) != NULL)
            apr_thread_mutex_lock(mutex);
#endif /* APR_HAS_THREADS */

        if ((*pool->ref = pool->sibling) != NULL)
            pool->sibling->ref = pool->ref;

#if APR_HAS_THREADS
        if (mutex)
            apr_thread_mutex_unlock(mutex);
#endif /* APR_HAS_THREADS */
    }

    //pool->self表示给予内存池内存的节点
    //active链表是循环链表,这里*active->ref=NULL是将链表变成pool->self为头的单链表。
    allocator = pool->allocator;
    active = pool->self;
    *active->ref = NULL;

#if APR_HAS_THREADS
    if (apr_allocator_owner_get(allocator) == pool) {
        apr_allocator_mutex_set(allocator, NULL);
    }
#endif /* APR_HAS_THREADS */

    /*将节点归还给分配器*/
    allocator_free(allocator, active);

    //如果分配器是该内存池所有,则销毁分配器。
    if (apr_allocator_owner_get(allocator) == pool) {
        apr_allocator_destroy(allocator);
    }
}
static APR_INLINE
void allocator_free(apr_allocator_t *allocator, apr_memnode_t *node)
{
    apr_memnode_t *next, *freelist = NULL;
    apr_uint32_t index, max_index;
    apr_uint32_t max_free_index, current_free_index;

#if APR_HAS_THREADS
    if (allocator->mutex)
        apr_thread_mutex_lock(allocator->mutex);
#endif /* APR_HAS_THREADS */

    max_index = allocator->max_index;
    max_free_index = allocator->max_free_index;
    current_free_index = allocator->current_free_index;

    /*遍历node,将节点放到free数组中或者归还系统。*/
    do {
        next = node->next;
        index = node->index;

        //如果节点大于current_free_index则释放节点,将内存放回给系统。
        if (max_free_index != APR_ALLOCATOR_MAX_FREE_UNLIMITED
            && index + 1 > current_free_index) {
            node->next = freelist;
            freelist = node;
        }
        //如果节点小于free最大索引,则插入对应的链表。
        else if (index < MAX_INDEX) {
            if ((node->next = allocator->free[index]) == NULL
                && index > max_index) {
                max_index = index;
            }
            //调整current_free_index
            allocator->free[index] = node;
            if (current_free_index >= index + 1)
                current_free_index -= index + 1;
            else
                current_free_index = 0;
        }
        //插入free[0]
        else {
            node->next = allocator->free[0];
            allocator->free[0] = node;
            if (current_free_index >= index + 1)
                current_free_index -= index + 1;
            else
                current_free_index = 0;
        }
    } while ((node = next) != NULL);

    //调整max_index与current_free_index的值
    allocator->max_index = max_index;
    allocator->current_free_index = current_free_index;

#if APR_HAS_THREADS
    if (allocator->mutex)
        apr_thread_mutex_unlock(allocator->mutex);
#endif /* APR_HAS_THREADS */

    //将多余内存还给系统
    while (freelist != NULL) {
        node = freelist;
        freelist = node->next;
#if APR_ALLOCATOR_USES_MMAP
        munmap(node, (node->index+1) << BOUNDARY_INDEX);
#else
        free(node);
#endif
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值