源码编译 nginx 时“内存不足溢出”实为构建阶段资源瓶颈,需检查系统内存与 swap、限制 make 并行数(如 -j2)、精简模块与调试符号、降低 gcc 优化等级(-o1)、清理旧构建产物,并排除磁盘满或权限问题。

源码编译 Nginx 时出现“内存不足溢出”,通常不是 Nginx 自身导致,而是编译过程(尤其是 make 阶段)耗尽了系统可用内存或虚拟内存,表现为 cc1: out of memory allocating XXX bytes、g++: internal compiler error: Killed (program cc1plus),或直接被 Linux OOM killer 终止。这不是运行时泄漏,而是构建阶段的资源瓶颈,需从环境、编译策略和模块三方面入手。
检查系统可用内存与编译进程开销
编译 Nginx(尤其含多个第三方模块或启用 --with-debug)会显著增加 GCC 内存占用,单线程编译常需 1–2GB RSS,多线程(make -jN)可能线性放大:
- 执行
free -h确认可用内存是否低于 1.5GB;若 swap 关闭或极小,swapon --show查看交换空间是否启用 - 用
ulimit -v检查虚拟内存限制(单位 KB),若输出为有限值(如 2097152 表示 2GB),运行ulimit -v unlimited临时解除 - 避免使用
make -j$(nproc):64 核机器默认并行 64 个编译任务极易爆内存;推荐make -j$(($(nproc)/2 + 1))或直接make -j2
精简编译选项与模块依赖
调试符号(-g)、高阶优化(-O2/-O3)、大量静态模块都会推高内存峰值。非调试场景应主动裁剪:
- 移除不必要的模块:例如不用 HTTP/3 就去掉
--with-http_v3_module;不需 GeoIP 就不加--with-http_geoip2_module - 禁用调试符号:除非定位编译器问题,否则不要加
--with-debug;若必须调试,改用--with-cc-opt="-g1"(最小化调试信息) - 降低优化等级:在
./configure中追加--with-cc-opt="-O1"替代默认-O2,可减少约 30% 编译内存消耗 - 确认第三方模块未引入冗余依赖:某些模块的
config文件会强制添加-O3或链接大型库(如 OpenSSL 静态编译),应手动注释其优化相关行
调整 GCC 与构建环境参数
GCC 本身提供内存控制开关,可缓解中间文件膨胀问题:
- 在
./configure命令末尾添加:--with-cc-opt="-fno-plt -frecord-gcc-switches -fno-asynchronous-unwind-tables",减少调试元数据体积 - 设置环境变量限制预编译头缓存:
export CCACHE_COMPRESS=1 CCACHE_COMPRESSLEVEL=3(若启用 ccache) - 编译前清空旧构建产物:
make clean && rm -rf objs/,避免残留的巨量.o文件叠加内存压力 - 对低内存设备(如 1GB VPS),可改用
clang替代gcc:配置时指定--with-cc=clang --with-cc-opt="-O1 -gline-tables-only",Clang 内存占用通常更低
验证是否为真实内存不足而非其他失败
部分报错看似内存问题,实为磁盘满、权限不足或工具链缺失:
- 检查
df -h /tmp和df -h /usr/src:GCC 默认在/tmp生成临时文件,若该分区满(100%),会伪造 “out of memory” 错误 - 运行
dmesg | tail -20:查找 “Out of memory: Kill process” 或 “fork failed” 等内核级提示,确认是否真被 OOM killer 干掉 - 尝试最小化构建:
./configure --prefix=/tmp/test && make -j1,若成功,则原命令中某模块或选项是罪魁祸首











