有输出基本就是OOM Killer干的;无输出不等于未发生,可能是日志清空、权限受限(如kernel.dmesg_restrict=1)或非内核触发,需结合sudo dmesg -T | tail -200、journalctl -k及/proc/PID/oom_score_adj综合判断。

直接看 dmesg -T | grep -i "killed process",有匹配输出基本就是 OOM Killer 干的;没输出不代表没发生,可能是日志被清空、权限受限,或根本不是内核触发的终止。
优先用 dmesg 定位核心证据
OOM Killer 只在内核 ring buffer 中写一次关键记录,dmesg 是唯一能原样读取它的工具。
- 加
-T参数让时间戳可读(如[Wed Jul 29 14:30:22 2026]),方便和你发现进程挂掉的时间对齐 - 典型输出形如:
[Wed Jul 29 14:30:22 2026] Killed process 18942 (python3) total-vm:4567890kB, anon-rss:3214567kB -
anon-rss是关键指标:代表该进程实际占用的物理内存(不含缓存/映射文件),若接近机器总内存,基本坐实是它撑爆了系统
查不到关键词?别急着下结论
日志丢失或权限限制很常见,先检查三件事:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 运行
sudo sysctl kernel.dmesg_restrict,若返回1,说明非 root 用户被禁止访问完整日志;临时放开:sudo sysctl kernel.dmesg_restrict=0 - 执行
sudo dmesg -c清空缓冲区(注意:会丢掉所有未读日志,生产环境慎用),再复现问题(例如跑stress --vm 1 --vm-bytes 3G) - 查落盘日志:
sudo grep -i "out of memory\|killed process" /var/log/messages或journalctl -k --since "2 hours ago"
光看“被杀”不够,得看“为什么杀”
dmesg 只告诉你结果,真正原因藏在前后几秒的日志里。OOM 不是突然发生的,通常伴随这些线索:
-
page allocation failure或low memory提示:说明内核连一个内存页都分不出去了 -
free:行:显示各内存 zone 剩余页数,数值极低就是硬扛不住了 - 如果是容器:
Memory cgroup out of memory更关键——说明不是整机内存不足,而是某个 cgroup 超限 - 建议用
sudo dmesg -T | tail -n 200拉最近 200 行,人工扫一遍 OOM 时间点前后 5 秒内的上下文
谁该先死?看 oom_score_adj 才是关键
被杀进程不一定是内存最大的那个,而是内核根据 oom_score_adj 综合评估后选定的:
- 查被杀进程当时的分数:
cat /proc/18942/oom_score_adj(替换 PID) - 对比同类进程:
ps -eo pid,comm,oom_score,oom_score_adj --sort=-oom_score | head -10 - root 进程默认为
-1000(免疫),普通用户进程默认为0,Docker 容器默认常设为1000










