oom-killed

进程被 OOM Killer 杀死的定位与修复

现象

进程突然消失,退出码为 137;dmesg 出现 Out of memory: Killed process。在 Kubernetes 里表现为 OOMKilled,容器反复重启。

快速定位

dmesg -T | grep -i -E 'oom|killed process'
journalctl -k --since '1 hour ago' | grep -i oom
free -m
ps aux --sort=-%mem | head -10
cat /proc/pressure/memory
cat /sys/fs/cgroup/memory.events 2>/dev/null

容器内查看 cgroup:

cat /sys/fs/cgroup/memory.max
cat /sys/fs/cgroup/memory.current
cat /sys/fs/cgroup/memory.events

常见根因

  1. 应用内存泄漏或一次性加载过多数据。
  2. 容器 memory.limit 低于实际峰值;JVM 堆外内存、线程栈、直接内存没算进去。
  3. 页面缓存和匿名内存争抢,宿主机整体内存不足。
  4. fork 炸弹、并发突增或批量任务没有限流。
  5. OOMScoreAdjust 让关键进程优先被杀。

修复

相关命令

读完自测

合上页面,先回答,再展开对照。

  1. 进程退出码 137 且 dmesg 出现 Killed process,重启前应先保留哪些现场?
  2. 容器已经设置了 memory limit,为什么仍可能被 OOMKilled?
  3. 能否通过关闭 OOM Killer 来“解决”问题?
答案
  1. 先保留 dmesg/内核日志、cgroup 计数和进程 RSS 曲线,再重启。页面把“先取现场”列为修复的第一步。
  2. limit 要覆盖实际峰值,JVM 堆外内存、线程栈和直接内存都要算进去。只按堆大小设置内存上限会漏算。
  3. 不能。页面建议调低非关键进程的 oom_score_adj,不要靠关 OOM Killer 解决。同时监控 memory.events 的 oom_kill 计数。