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

Ubuntu 下 nginx-1.24.0 源码分析 - NGX_MAX_ALLOC_FROM_POOL

NGX_MAX_ALLOC_FROM_POOL

定义在 src\core\ngx_palloc.h

#define NGX_MAX_ALLOC_FROM_POOL  (ngx_pagesize - 1)

在 src/os/unix/ngx_alloc.h

extern ngx_uint_t  ngx_pagesize;

这个全局变量定义在

src\os\unix\ngx_alloc.c 中

ngx_uint_t  ngx_pagesize;

在 src/os/unix/ngx_posix_init.c

ngx_int_t
ngx_os_init(ngx_log_t *log)
{
    ngx_time_t  *tp;
    ngx_uint_t   n;
#if (NGX_HAVE_LEVEL1_DCACHE_LINESIZE)
    long         size;
#endif

#if (NGX_HAVE_OS_SPECIFIC_INIT)
    if (ngx_os_specific_init(log) != NGX_OK) {
        return NGX_ERROR;
    }
#endif

    if (ngx_init_setproctitle(log) != NGX_OK) {
        return NGX_ERROR;
    }

    ngx_pagesize = getpagesize();

这里被赋值


getpagesize 函数用于获取系统的内存页大小(page size)。

内存页是操作系统管理内存的基本单位,通常以字节为单位。

不同的操作系统和硬件架构可能会有不同的页大小,常见的页大小有 4KB、8KB、16KB 等。


getpagesize 函数返回系统的页大小,单位为字节(bytes)

为了使用 getpagesize 函数,你需要包含以下头文件:

#include <unistd.h>

在第一次使用时(main 函数中首次使用 ngx_create_pool)

 p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;

这里 还未执行 ngx_os_init 函数,ngx_pagesize 还未被赋值(初始值为0,64 位无符号整数 - 1 = 18446744073709551615)

所以这里 p->max 的值是 size 的值


NGX_MAX_ALLOC_FROM_POOL 为什么要设置为 ngx_pagesize - 1?

避免跨页分配

a. 内存页的概念
  • 操作系统以页(page)为单位管理内存,常见的页大小为 4KB(4096 字节)或 8KB(8192 字节)。
  • 分配内存时,操作系统通常会按页分配,即使只需要少量内存,也会分配整个页。
b. 跨页分配的问题
  • 如果从内存池中分配的内存块大小接近或等于一页(如 4096 字节),可能会导致跨页分配。
  • 跨页分配会增加内存管理的复杂性,并可能导致性能下降。例如:
    • 缓存未命中率增加:数据分布在多个缓存行中,访问效率降低。
    • 内存对齐问题:跨页分配可能导致未对齐访问,影响性能。

  • 将最大分配大小限制为 ngx_pagesize - 1,可以确保分配的内存块始终位于单个页内,避免跨页问题。
  • 例如,如果页大小为 4096 字节,则 NGX_MAX_ALLOC_FROM_POOL 的值为 4095 字节,确保分配的内存不会跨越页边界。

提高内存利用率

a. 小块内存分配
  • Nginx 的内存池主要用于分配小块内存(如 HTTP 请求头、连接上下文等)。
  • 这些小块内存的大小通常远小于 ngx_pagesize,因此将最大分配大小限制为 ngx_pagesize - 1 可以充分利用内存池的空间。
b. 大块内存分配
  • 如果需要分配的内存大小超过 ngx_pagesize - 1,Nginx 会使用单独的大块内存分配机制(通过 large 链表管理)。
  • 这种设计可以避免大块内存占用内存池空间,从而提高内存池的利用率。

简化内存管理

a. 内存池的设计目标
  • 内存池的设计目标是高效地管理小块内存分配。
  • 如果允许从内存池中分配过大的内存块,可能会增加内存池的复杂性。例如:
    • 需要额外的链表或数据结构来跟踪大块内存的使用情况。
    • 剩余的内存空间可能不足以满足其他分配请求,导致内存浪费。
b. 分离小块和大块内存
  • 通过将最大分配大小限制为 ngx_pagesize - 1,可以将小块内存和大块内存的管理逻辑分离:
    • 小块内存直接从内存池中分配,管理简单高效。
    • 大块内存通过单独的分配机制(如 mallocngx_alloc)进行管理,避免干扰内存池。

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

相关文章:

  • 基于智能体和RWA的分布式商业生态商业模型架构设计
  • 数字化到“数智化”:AI重构商业世界的底层逻辑
  • 【Prometheus】prometheus结合pushgateway实现脚本运行状态监控
  • PyQt加载UI文件
  • HarmonyOS NEXT 5.0.0.126 最新升级内容详解
  • 浅谈模组-相机鬼像
  • 【面试题系列】Java 多线程面试题深度解析
  • 硕成C语言24
  • 【核心算法篇二】《DeepSeek NLP实战:BERT/GPT/LLM全系调优》
  • MySQL5.7 创建用户并授予超管权限脚本
  • 在 Ubuntu 22.04 中修改主机名称(hostname)
  • Neo4j集群学习
  • 开源在线考试系统开源在线考试系统:支持数学公式的前后端分离解决方案
  • 2025最新智能优化算法:改进型雪雁算法(Improved Snow Geese Algorithm, ISGA)求解23个经典函数测试集,MATLAB
  • Java 面试篇-Redis 专题(Redis 常见的面试专题:缓存击穿、缓存雪崩、缓存穿透、什么是布隆过滤器、什么是延时双删、持久化的方式、Redis 分布式锁、I/O 多路复用等等)
  • ​实在智能与宇树科技、云深科技一同获评浙江省“人工智能服务商”、 “数智优品”​等荣誉
  • Linux-权限维持
  • Go入门之流程控制
  • HTTP FTP SMTP TELNET 应用协议
  • Farewell Go,Hello AI:是时候说再见了