最可靠方式是执行dmesg -t | grep -i "killed process",因oom killer仅在内核ring buffer写一次关键记录;无输出不等于未发生,可能因log_buf_len过小、kernel.dmesg_restrict=1权限限制或日志被覆盖,需结合journalctl -k、/var/log/messages及exit code 137交叉验证。

dmesg没输出不等于没被OOM Killer杀
直接执行 dmesg -T | grep -i "killed process" 没结果,不能排除OOM Killer作案。内核ring buffer容量有限,日志可能已被新消息覆盖;更常见的是权限限制或缓冲区太小导致关键行丢失。
先检查是否被权限拦住:sudo sysctl kernel.dmesg_restrict。若返回 1,说明非 root 用户看不到完整内核日志——临时放开:sudo sysctl kernel.dmesg_restrict=0,再重试 dmesg -T。
再确认缓冲区大小:cat /proc/sys/kernel/log_buf_len。低于 1048576(1MB)就容易丢日志,尤其在高负载下。云主机或容器环境常默认设得很小。
- 不是所有“Killed”都是OOM:也可能是
SIGKILL(如kill -9)、systemd 重启、cgroup memory limit 超限触发的静默终止 -
exit code 137是重要线索:shell 中137 = 128 + 9,代表被SIGKILL杀死,而 OOM Killer 发出的正是这个信号 - 如果程序是 systemd service,查
systemctl status -n100 your-service,看是否有State: failed和ExitCode=137
journalctl -k 是第二道防线
journalctl -k 读取的是内核日志的持久化副本,即使 dmesg 缓冲区清空了,只要 journal 还没轮转,它就可能保留记录。
重点命令:journalctl -k --since "1 hour ago" | grep -i -E "(out of memory|killed process|oom-killer)"。加时间范围能避开海量历史日志,提高命中率。
注意:journalctl -k 在某些发行版(如 RHEL 8+)默认只存最近几次 boot 的日志。若服务是长期运行的,且系统没重启过,这条命令比 dmesg 更可靠。
在无 root/sudo 权限的环境(云容器、VPS、隔离主机)中安装并配置 OpenClaw 浏览器工具的 headless Chrome。适用场景:...
- 如果
journalctl -k也没结果,别急着放弃——检查/var/log/messages或/var/log/kern.log:sudo grep -i "killed process" /var/log/messages - 某些云厂商镜像会关闭内核 OOM 日志详细输出,此时
journalctl -k可能只显示Out of memory: System overloaded这类模糊提示,需结合内存指标交叉判断
用 exit code + 时间戳反向锁定被杀进程
你的 C++ 程序挂掉时,shell 或日志里大概率留有 exit code 137。这是最硬的证据之一——OOM Killer 杀进程只会用 SIGKILL,不会用 SIGTERM 或其他信号。
拿到退出时间后,立刻查该时刻前后 30 秒的内核上下文:sudo dmesg -T | awk -v t="$(date -d '2026-09-30 08:45:22' '+%b %d %H:%M')" '$0 ~ t {for(i=NR-5;i(把时间替换成你的真实退出时间)。
更简单的方法是用 tail 扫描近 200 行:sudo dmesg -T | tail -n 200 | grep -A5 -B5 -i "out of memory",人工看时间是否对得上。
- 如果程序跑在容器里,
docker inspect <container></container>查State.ExitCode和State.OOMKilled字段,后者为true就是铁证 - 如果是 systemd service,
systemctl show --property=OOMScoreAdjust your-service能看出是否被主动调高了被杀优先级 -
cat /proc/meminfo | grep -E "(MemAvailable|Committed_AS|CommitLimit)":若Committed_AS接近CommitLimit,说明内核早认定内存承诺超限,只是还没触发 killer
anon-rss 接近总内存才是 OOM 的核心依据
就算你从日志里揪出了 Killed process 12345 (myapp),也不能武断归因为 OOM——关键要看 anon-rss 值。
这个字段代表进程实际占用的匿名物理内存(不含文件缓存、共享内存等),单位是 kB。如果它接近机器总内存(比如 64GB 机器上看到 anon-rss:62345678kB),基本可以闭眼认定是它撑爆了系统。
而 total-vm 没啥参考价值:它只是虚拟地址空间大小,32 位程序最多 4GB,64 位轻松上 TB,远超物理内存,不能说明问题。
- 查不到
anon-rss?说明日志被截断。优先用dmesg -T | grep -A10 -B5 "Killed process",多抓几行上下文,常能在前/后行看到comm=xxx或完整内存字段 - 如果进程是短命的(启动几秒就挂),
/proc/PID/status来不及写入,但journalctl -k或dmesg的原始输出里仍会保留那一行anon-rss - 真正难缠的是 cgroup 级别 OOM:日志里只写
Memory cgroup out of memory,不提具体进程。这时得去查/sys/fs/cgroup/memory/<cgroup-path>/memory.usage_in_bytes</cgroup-path>和tasks
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










