重载后内存翻倍是因新旧worker并存导致进程堆积,非内存泄漏;需通过ps查PID/PPID、error.log搜abort/shutdown、ipcs看shm段、pmap分析[anon]/[heap]来确认是否旧worker卡在shutdown状态。

重载后内存翻倍,不是配置“生效了”,而是旧 worker 没退干净、新 worker 又全拉起来了——本质是进程堆积,不是内存泄漏。
看进程是否真实切换完成
执行 nginx -s reload 后,别只信 systemctl status nginx。要直接查进程:
- 运行
ps -eo pid,ppid,comm,args | grep nginx,确认 master 进程 PID 不变(正常),但旧 worker 的状态应为shutdown,且数量在逐步减少 - 若发现大量 worker 进程 PID 持续存在、RSS 值未下降,或新旧 worker 同时稳定在高位(比如原来 4 个 worker 占 200MB,重载后变成 8 个占 400MB),说明旧 worker 卡在 shutdown 状态没退出
- 特别注意:
ps输出中若看到多个相同启动时间的 worker,或PPID指向非 master 进程,大概率是异常 fork 或残留进程
查日志里有没有 abort 和 socket 残留
打开错误日志实时观察重载瞬间:
tail -f /var/log/nginx/error.log | grep -E "(aborting|open socket left|shutdown)"- 出现
aborting表示 worker 被强制终止,常见于运维手动kill -9shutdown 中的进程 - 出现
open socket left in connection是典型信号处理失败表现:worker 退出前没来得及关闭连接,socket 句柄滞留,内核持续为其保留缓冲区(含接收/发送队列),这部分内存不会计入 RSS,但实际占用物理页框,free -h会显示 cached/buffers 异常偏高
验证临时文件与共享内存是否重复创建
重载本身不释放已分配的共享资源,但某些配置变更会触发新区域初始化:
- 运行
ipcs -m | grep nginx,对比重载前后共享内存段(shm)数量和 key;若新增了 zone(如ssl_session_cache、limit_req_zone),而旧 zone 未被复用,就会双份驻留 - 检查
proxy_temp_path、client_body_temp_path目录下文件增长:重载不会清空 temp 目录,但若新 worker 因缓存逻辑变化(如proxy_buffering off → on)开始大量写临时文件,而旧 worker 仍持有已删除但未 close 的句柄(lsof | grep deleted | grep nginx),磁盘和内存都会虚高 - 用
pmap -x $(pgrep nginx | head -n1)查单个 worker 内存映射,重点关注[anon]区域(堆分配)和[heap]是否异常膨胀,而非只盯总 VIRT
快速隔离:跳过配置变更,只做空 reload
排除配置本身导致内存增长的干扰:
- 备份当前配置,然后用最简配置测试:
echo "events{worker_connections 1024;} http{server{listen 80;return 200 'ok';}}" > /tmp/min.conf - 执行
nginx -c /tmp/min.conf -t && nginx -s reload(确保 master 进程仍在,仅替换配置) - 观察 RSS 是否仍翻倍:如果依然翻倍,问题锁定在进程模型或系统层(如 ulimit、cgroup 限制、OOM Killer 干预);如果恢复正常,说明原配置中某项(如
proxy_buffers、large_client_header_buffers、第三方模块)在重载时被重复初始化


















