异步事件驱动模型使Nginx通过共享预分配内存、按需切分连接/请求级子池、批量释放实现单连接内存开销最小化:连接不独占堆,仅复用worker统一缓冲区与状态机;小对象走池内偏移分配,大文件启用sendfile零拷贝,精简配置规避隐性内存消耗。

异步事件驱动模型让 Nginx 不为每个连接单独分配一套运行时结构,而是共享资源、按需切分、批量释放,从而把单连接内存开销压到最低。
连接不独占内存池,只共享预分配块
传统服务器(如 Apache prefork)每建立一个连接就 fork 一个进程,每个进程自带完整堆空间、缓冲区和上下文,内存随连接数线性增长。Nginx 的 worker 进程在启动时就预分配好一块连续内存(如主 pool),所有连接共用这套基础结构;新连接仅注册事件监听器、复用已有 socket 缓冲区和状态机变量,不额外 malloc 堆内存。
- 连接级内存池在 accept 时从主池划出小块,生命周期与连接一致,关闭即整块归还
- 没有 per-connection 的独立堆分配,避免了 glibc malloc 的元数据膨胀和碎片累积
- socket 读写缓冲区(如 recv_buffer)由 worker 统一管理,多个连接复用同一组 buffer 池
请求级资源轻量化,生命周期严格绑定
HTTP 请求的 header 解析、临时变量、重写上下文等,都从连接池中再切出子池(request pool)。这个子池极轻量——通常仅几 KB,且只存本次请求所需,响应结束立即销毁,不留残留。
- 小对象(≤4KB)全部走内存池偏移分配,无系统调用,无锁竞争
- 禁止在 request pool 中缓存大 body 或长期数据;需落盘时用临时 buf 并显式归还
- pool 指针绝不跨请求传递,避免悬挂引用导致内存泄漏或崩溃
零拷贝传输绕过用户态缓冲
当返回静态文件时,若走 read + write 路径,数据要先 copy 到用户态 buffer 再 send 出去,单次传输至少占用两倍 buffer 空间。Nginx 用内核级路径规避这一开销:
- sendfile on;:文件页缓存直推 socket,不经过用户态内存
- tcp_nopush on;:攒满 TCP 包再发,减少小包数量及关联 buffer 占用
- 大文件读取启用 aio on; directio 4k;,异步读取且跳过 page cache,避免缓存抖动
精简配置减少隐性内存消耗
很多内存不是被连接本身吃掉,而是被未关闭的功能悄悄占用:
- 禁用 access_log 或启用 buffer=64k flush=5s,避免高频日志写入触发临时 buffer 分配
- 关闭 server_tokens,省去版本字符串拼接与复制开销
- 慎用 map 指令构建动态哈希表——它常驻内存且扩容不释放旧空间;高频路由改用 if + return 静态判断
- 编译时剔除不用模块(如 --without-http_perl_module),减少初始化阶段的全局结构体



















