OOM 杀进程需查内核日志:执行 dmesg -T | grep -i "killed process" 和 grep -i "out of memory" /var/log/syslog,比对时间点与 Nginx 错误日志是否一致;再用 ps aux --sort=-%mem | head -10 与 PHP-FPM 状态页定位内存异常 worker,结合 /proc/PID/smaps 分析 Rss/Pss;临时止血配置 rlimit_as、pm.max_requests 及 Nginx proxy_next_upstream;根因需排查代码级内存泄漏。

直接看内核日志,别只盯 Nginx 或 PHP-FPM 自己的日志——OOM 是系统级行为,痕迹全在 kernel 里。
确认是否真被 OOM 杀掉
执行这条命令:
dmesg -T | grep -i "killed process"
如果输出里出现 php-fpm、nginx worker 或你实际的进程名(比如 www),并带时间戳,基本就坐实了。再补查一句:
立即学习“PHP免费学习笔记(深入)”;
grep -i "out of memory" /var/log/syslog(或 /var/log/messages)
比对日志里 OOM 时间点,和 Nginx error.log 中首次出现 upstream prematurely closed connection 或 connect() failed (111: Connection refused) 的时间是否吻合。一致的话,就是它。
看内存到底涨到多离谱
不是看平均值,是找“ outlier”:
- 用 ps aux --sort=-%mem | head -10 查当前内存占用最高的进程,重点盯 php-fpm worker
- 进 PHP-FPM 状态页:curl http://127.0.0.1/status?full(需提前配好
pm.status_path),看每个 worker 的memory_usage字段。如果多数是 80MB,突然有个是 1.5GB,那就是泄漏点 - 挑一个高内存的 worker,查它的详细分布:cat /proc/PID/smaps | awk '/^Rss:/ {sum+=$2} END {print sum " kB"}',再结合
Pss行判断共享内存占比,排除误判
临时止血,防止雪崩
根因修复前,必须加防护层:
- PHP-FPM 配置里加:rlimit_as = 512M(限制单个 worker 虚拟内存上限),再设 pm.max_requests = 500,强制轮换释放累积内存
- Nginx 配置里加:proxy_next_upstream error timeout http_502 http_504; max_fails=2 fail_timeout=15s,避免请求持续打向刚被 kill 的残缺后端池
- 系统级调一下:echo 2 > /proc/sys/vm/overcommit_memory,让内核更严格地评估内存申请,减少误杀
后续要深挖泄漏源头
OOM 是结果,不是原因。得顺着进程找代码问题:
- PHP:检查有没有大数组没 unset、GD 图像资源没 imagedestroy、PDO 长连接未 close、或启用 opcache 但没配好内存大小
- Python(如果混用):关注 pandas DataFrame、requests session 复用、文件句柄未 close、缓存未 TTL 清理
- Java(同理):jstat -gc PID 看老年代 OU 是否持续不降,GC 日志里是否有频繁 Full GC 却回收很少



















