nginx本身不直接启用mmap,但可通过关闭sendfile、启用aio及优化open_file_cache,使小中型静态文件(≤128mb)按需映射至虚拟内存,实现零拷贝、页缓存共享与缺页加载,显著提升读取性能。

Nginx 使用 mmap 提升静态文件读取性能,核心在于绕过传统 I/O 的数据拷贝和系统调用开销,让文件内容“直接可见”于进程地址空间。
mmap 如何加速 Nginx 静态文件服务
Nginx 默认不启用 mmap,但可通过配置 sendfile off; + aio on;(部分场景)或更直接地配合 open_file_cache 与底层内核行为协同;真正发挥 mmap 效能的典型路径是:当 Nginx 以 mmap 方式打开并映射小至中等尺寸的静态文件(如 CSS、JS、图标)时,它不再调用 read() 逐块读取,而是将文件页按需映射进虚拟内存。后续对文件的访问(例如发送响应体)可直接通过内存指针操作——内核自动将缺页触发的磁盘加载与页缓存复用整合进来。
- 文件首次被
mmap()映射时,内核只建立虚拟内存区域(VMA),不加载数据 - 第一次读取某一页时触发缺页中断,内核从磁盘加载该页到页缓存,并映射到用户空间虚拟地址
- 后续访问同一页面无需拷贝,CPU 直接读取页缓存中的内容,实现零拷贝
- 多个 worker 进程映射同一文件时,共享底层物理页缓存,降低内存占用
适用条件与实际限制
Nginx 并非对所有文件都启用 mmap,是否使用取决于文件大小、mmap 配置策略及内核支持:
- 文件必须小于
mmap的安全阈值(通常建议 ≤ 128MB),过大可能引发虚拟内存碎片或 OOM - 需满足页对齐:
offset和length均需是getpagesize()的整数倍,否则映射失败或行为未定义 -
mmap映射的文件在munmap前持续占用 VMA 资源,频繁映射/解除映射会增加内核开销 - 若启用了
sendfile(默认开启),Nginx 优先走内核零拷贝路径(sendfile()系统调用),此时mmap不生效——二者互斥
如何在 Nginx 中间接利用 mmap 优势
虽然 Nginx 没有暴露 mmap 的显式开关,但可通过以下方式使其更倾向使用内存映射类行为:
- 关闭
sendfile(sendfile off;),启用aio threads;或directio,为mmap创造执行路径 - 设置
open_file_cache max=10000 inactive=60s;,提升文件句柄与元数据缓存命中率,减少重复open/mmap - 对热静态资源(如前端构建产物),确保其驻留页缓存:可用
posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED)预热(需定制模块或内核支持)
不复杂但容易忽略











