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

Nginx内存池源代码剖析----ngx_create_pool函数

ngx_create_pool 是 Nginx 内存池 的初始化函数,负责创建并初始化一个内存池对象。它的作用是 为后续的内存分配操作提供统一的管理入口,通过预分配一块较大的内存区域,并基于此区域实现高效的内存分配、对齐管理和资源回收。

源代码定义:

ngx_pool_t *
ngx_create_pool(size_t size, ngx_log_t *log)  // 根据size大小开辟内存池
{
    ngx_pool_t  *p;

    p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log); // 对齐分配内存
    if (p == NULL) {
        return NULL;
    }

    p->d.last = (u_char *) p + sizeof(ngx_pool_t);  // 给头信息赋值
    p->d.end = (u_char *) p + size;
    p->d.next = NULL;
    p->d.failed = 0;

    size = size - sizeof(ngx_pool_t);  // 内存池能使用的大小
    p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;  // 当前小块分配的最大值

    p->current = p; // 指向起始地址
    p->chain = NULL;
    p->large = NULL;
    p->cleanup = NULL;
    p->log = log;

    return p;
}

代码解析

用到的数据类型定义:
在这里插入图片描述在这里插入图片描述
ngx_pool_data_t 结构体

last:指向当前内存池中可用内存的起始地址。
end:指向当前内存池的末尾位置。
next:指向下一个内存池块,用于链接多个内存池。
failed:记录当前内存池分配失败的次数。当失败次数超过一定阈值时,Nginx 会跳过该内存池,直接尝试从下一个内存池分配内存。

ngx_pool_s 结构体

d:内存池的核心数据块,包含可用内存的起始地址、末尾位置、下一个内存池块等信息。
max:当前内存池可分配的最大内存大小。如果请求的内存大小超过 max,则从大内存块链表(large)中分配。
current:指向当前可用的内存池。当当前内存池的空间不足时,Nginx 会尝试从 current 指向的下一个内存池分配内存。
chain:用于链表管理,通常与 Nginx 的缓冲区(ngx_buf_t)相关。
large:指向大内存块链表。当请求的内存大小超过 max 时,Nginx 会从大内存块链表中分配内存。
cleanup:清理回调函数链表。当内存池销毁时,Nginx 会调用这些回调函数来释放资源。
log:日志对象,用于记录内存池的相关日志信息。

在这里插入图片描述
ngx_create_pool函数执行流程:
在这里插入图片描述

使用 ngx_memalign 函数分配一块对齐的内存。NGX_POOL_ALIGNMENT 是内存对齐的边界(通常是
16 字节)。 如果分配失败,返回 NULL。

在这里插入图片描述

last 指向内存池中可用内存的起始地址,跳过 ngx_pool_t 结构体本身。
end 指向内存池的末尾位置。
next 初始化为 NULL,表示当前没有下一个内存池块。
failed 初始化为 0,表示当前内存池尚未发生分配失败。

在这里插入图片描述

计算内存池中实际可用的内存大小(减去 ngx_pool_t 结构体本身的大小)。
max 表示当前内存池可分配的最大内存大小。如果可用内存大小小于 NGX_MAX_ALLOC_FROM_POOL(通常是 4KB),则使用可用内存大小;否则使用 NGX_MAX_ALLOC_FROM_POOL。

ngx_create_pool 函数的作用是:

  1. 分配一块对齐的内存,并初始化内存池的核心数据结构。
  2. 管理可用内存的起始地址和末尾位置,确保内存分配的高效性。
  3. 支持大内存块和小内存块的分离,减少内存碎片。
  4. 提供日志和清理机制,方便调试和资源管理。
    通过这种设计,Nginx 的内存池能够高效地管理内存分配和释放,减少内存碎片,并提高性能。

相关文章:

  • AI 新动态:技术突破与应用拓展
  • 【万字详细教程】Linux to go——装在移动硬盘里的Linux系统(Ubuntu22.04)制作流程;一口气解决系统安装引导文件迁移显卡驱动安装等问题
  • 机器学习实战(4):逻辑回归——分类问题的基础
  • 【git-hub项目:YOLOs-CPP】本地实现03:跑自己的实例分割模型
  • Kafka
  • 训练数据为什么需要Shuffle
  • 如何使用qt开发一个xml发票浏览器,实现按发票样式显示
  • Java 设计模式之命令模式
  • 分布式 IO 模块:食品罐装产线自动化与高效运行的推手
  • 个人搭建CDN加速服务 特网科技
  • 解决vue-awesome-swiper 4.x + swiper 5.x 分页pagination配置不生效问题
  • Dify本地安装
  • 开源在线考试系统开源在线考试系统:支持数学公式的前后端分离解决方案
  • 动态内存管理
  • 栈与队列(C语言版)
  • 数据分析简介及其常用指标与方法
  • 毕业设计—基于Spring Boot的社区居民健康管理平台的设计与实现
  • java接口
  • DeepSeek教unity------Dotween
  • 部署postgresql_exporter监控pgsql
  • 荣盛发展:新增未支付债务11.05亿元
  • 哪条线路客流最大?哪个站点早高峰人最多?上海地铁一季度客流报告出炉
  • 白玉兰奖征片综述丨海外剧创作趋势观察:跨界·融变·共生
  • 广西壮族自治区党委副书记、自治区政府主席蓝天立接受审查调查
  • 探秘多维魅力,长江经济带、珠三角媒体总编辑岳阳行启动
  • A股三大股指低收:汽车股领涨,大金融走弱,两市成交近1.1万亿元