← 中文资源

简体中文版本

Linux OOM killer — 定位被杀进程并避免再次发生

通过 dmesg 与 journalctl 读取 OOM 报告,确认被杀进程与 cgroup 限制,修复泄漏、并发与内存规格,而不是关闭 overcommit。

阅读英文原文

现象

进程毫无征兆消失,应用层没有错误日志;dmesg 出现 Out of memory: Killed process 及 PID 与 total-vm;服务在压力下反复重启;SSH 或定时任务也被杀,但系统仍有部分响应。

诊断

先读内核报告并确认内存压力:

dmesg -T | grep -iE 'out of memory|killed process|oom' | tail -30
journalctl -k --since "1 hour ago" | grep -iE 'oom|killed process' | tail -30
cat /proc/meminfo | head -10
systemd-cgtop -m --iterations=1 | head -15
ps aux --sort=-%mem | head -15
cat /proc/$(pgrep -n java)/oom_score

报告会给出被杀进程的 RSS、total-vm 以及触发分配,oom_score 解释为何选中它。MemAvailable 接近 0 说明主机整体压力;若 cgroup 用量正好等于其上限,即使主机还有空闲内存也会在容器内触发 OOM。选进程时要关注 RSS 持续增长且 oom_score 高的那个,它就是下一个受害者。

修复

修复泄漏或给缓存设置上限,降低 worker 与线程并发,按实测峰值 RSS 加余量设置容器与 systemd 的 MemoryMax。关键服务可通过 oom_score_adj 或 MemoryMin 获得保护,但绝不能设为 -1000,否则泄漏进程无法被杀会拖死整机。批处理任务应限制在独立 cgroup 中,避免挤占交互服务;只有工作集确实超过物理内存时才增加内存或 swap。

验证

按相同负载复跑,MemAvailable 应始终高于安全余量,dmesg 与 journal 不再出现新的 OOM 记录;被杀进程的 RSS 峰值低于其 cgroup 上限,服务在整个压测过程中保持响应。若仍然被杀,先用 smem 或堆分析抓分配模式,而不是直接加内存,否则下一次峰值仍会重演。