当前位置: 首页 > article >正文

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_destroy_pool 函数

ngx_destroy_pool

声明src\core\ngx_palloc.h

void ngx_destroy_pool(ngx_pool_t *pool);

实现src\core\ngx_palloc.c

void
ngx_destroy_pool(ngx_pool_t *pool)
{
    ngx_pool_t          *p, *n;
    ngx_pool_large_t    *l;
    ngx_pool_cleanup_t  *c;

    for (c = pool->cleanup; c; c = c->next) {
        if (c->handler) {
            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                           "run cleanup: %p", c);
            c->handler(c->data);
        }
    }

#if (NGX_DEBUG)

    /*
     * we could allocate the pool->log from this pool
     * so we cannot use this log while free()ing the pool
     */

    for (l = pool->large; l; l = l->next) {
        ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
    }

    for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
        ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                       "free: %p, unused: %uz", p, p->d.end - p->d.last);

        if (n == NULL) {
            break;
        }
    }

#endif

    for (l = pool->large; l; l = l->next) {
        if (l->alloc) {
            ngx_free(l->alloc);
        }
    }

    for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
        ngx_free(p);

        if (n == NULL) {
            break;
        }
    }
}

ngx_destroy_pool 函数的作用与意图分析

ngx_destroy_pool 是 Nginx 内存池(ngx_pool_t)的核心销毁函数,其作用是彻底释放内存池管理的所有资源,确保无内存泄漏。

  • 资源回收
    释放内存池占用的所有内存块(包括小块内存和大块内存),并关闭或清理与内存池关联的外部资源(如文件句柄、锁等)。
  • 防止内存泄漏
    确保所有通过内存池分配的内存(无论是直接分配还是通过清理回调间接关联的资源)都被正确释放。

函数签名

void ngx_destroy_pool(ngx_pool_t *pool);

1. 返回类型 (void)

  • 含义:函数不返回任何值。
  • 原因
    该函数的设计目的是彻底销毁内存池并释放所有相关资源。
    销毁操作是“一次性”的,无需向调用者返回状态或结果。
    若释放过程中出现错误(如内存无法回收),Nginx 通常会通过日志记录问题,但不会通过返回值通知调用者

2. 参数 (ngx_pool_t *pool)

  • 类型ngx_pool_t *
    指向 Nginx 内存池结构体的指针。
  • 作用
    该参数指定需要被销毁的内存池对象。内存池中可能包含以下资源:
    • 内存块链表:由 ngx_pool_t 结构串联的多个内存块(用于小内存分配)。
    • 大块内存分配(large 链表):通过 ngx_allocngx_memalign 直接分配的大块内存。
    • 清理回调(cleanup 链表):注册的资源释放函数(如关闭文件句柄、释放锁等)。
  • 约束
    调用者必须确保 pool 是一个已初始化且未被销毁的有效指针,否则可能导致未定义行为(如双重释放或空指针解引用)。

详解

1. 执行清理回调

    for (c = pool->cleanup; c; c = c->next) {
        if (c->handler) {
            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
                           "run cleanup: %p", c);
            c->handler(c->data);
        }
    }

pool->cleanup

遍历 cleanup 链表,调用每个节点的 handler 函数,释放外部资源,调试日志会记录清理过程

  • 意图
    提供一种机制,允许用户将非内存资源(如文件、网络连接)的生命周期与内存池绑定,简化资源管理。

2. 释放大块内存(Large Allocations)

for (l = pool->large; l; l = l->next) {
    if (l->alloc) {
        ngx_free(l->alloc);
    }
}
  • 作用
    遍历 large 链表,释放所有分配的大块内存(超过 pool->max 阈值的内存)。
  • 意图
    大块内存无法通过内存池的小块分配机制管理,需单独释放,避免内存泄漏。

ngx_free 定义在 src/os/unix/ngx_alloc.h

#define ngx_free          free

3. 释放内存池自身内存块

for (p = pool, n = pool->d.next; ; p = n, n = n->d.next) {
    ngx_free(p);
    if (n == NULL) {
        break;
    }
}
  • 作用
    遍历内存池的内存块链表(由 ngx_pool_t 结构串联),逐个释放每个内存块(包括初始块和后续扩展块)。
  • 意图
    彻底释放内存池占用的所有内存,包括:
    • 初始内存块(ngx_create_pool 分配的内存)。
    • 后续通过 ngx_palloc_block 分配的扩展块。

http://www.kler.cn/a/569603.html

相关文章:

  • LSTM预测模型复现笔记和问题记录
  • 第10篇:文件IO与数据持久化(下)(JSON、二进制文件)
  • Junit框架缺点
  • 神经网络之词嵌入模型(基于torch api调用)
  • Vue3 中 defineOptions 学习指南
  • Docker-CE的部署、国内镜像加速
  • Redis(八):Redis分布式锁实现
  • 深入了解 K-Means 聚类算法:原理与应用
  • 介绍 torch-mlir 从 pytorch 生态到 mlir 生态
  • Android Binder 用法详解
  • 智能AI替代专家系统(ES)、决策支持系统(DSS)?
  • SpringDoc和Swagger使用
  • 深入理解并解析C++ stl::vector
  • MySQL 中如何查看 SQL 的执行计划?
  • 部署Joplin私有云服务器postgres版-docker compose
  • 1JVM概念
  • C# 上位机---INI 文件
  • 基于javaweb的SSM+Maven鲜花商城管理系统设计和实现(源码+文档+部署讲解)
  • 使用haproxy实现MySQL服务器负载均衡
  • Hive之正则表达式