应使用dmesg -w | grep -i "killed process\|out of memory"实时监听OOM日志,因其直接读取ring buffer、低延迟、字段完整;需sudo权限并注意缓冲区覆盖风险。

实时捕获 dmesg 中的 OOM killer 触发日志
不能靠 dmesg -T | grep 事后翻找,得让输出“活”起来。最直接有效的方式是用 dmesg -w(watch 模式),它会持续监听内核 ring buffer 新增条目,配合 grep 过滤关键词即可实现实时响应:
-
dmesg -w | grep -i "killed process\|out of memory"—— 最小可行命令,但注意grep默认带缓冲,可能延迟数秒;加--line-buffered更可靠 - 若终端不支持 ANSI 转义或想避免颜色干扰,加
--color=never - 不要用
tail -f /var/log/kern.log替代:该文件依赖 rsyslog/syslog-ng 是否配置了 kernel facility 日志转发,很多生产环境默认不记录 OOM 行为
为什么 dmesg -w 比 journalctl -f 更适合盯 OOM
journalctl -k -f 看的是内核日志流,但 OOM killer 的关键字段(如 Killed process XXX (java)、total-vm、anon-rss)在 dmesg 原始输出中更完整、无截断。journalctl 可能因日志格式化丢失部分内存统计细节,尤其在高负载下日志行被合并或省略。
-
dmesg -w直接读 ring buffer,零中间层,延迟最低 -
journalctl -k本质是把dmesg输出再喂给 journald,多一层解析,且默认启用日志压缩/截断策略 - 验证方式:
dmesg -w和journalctl -k -f同时运行,手动触发一次 OOM(如stress-ng --vm 1 --vm-bytes 10G),对比两者的输出完整性
过滤关键词必须包含哪些字符串
只搜 "oom" 或 "kill" 容易漏掉或误报。OOM killer 的日志有固定模式,应组合匹配以下三类关键词:
-
"Out of memory"—— 触发判定主句,出现在oom_kill_process()调用前 -
"Killed process"—— 实际执行杀进程的动作,含 PID、命令名、内存快照,最关键 -
"oom_kill_process"—— 内核函数名,出现在部分 debug 日志或较新内核中,可作为辅助确认 - 错误写法:
grep -i "oom"→ 会匹配到oom_score_adj设置日志、cgroup oom event 计数器等无关内容
容易忽略的权限与缓冲区限制
非 root 用户执行 dmesg -w 可能看不到完整日志,且 ring buffer 容量有限,高频日志下旧 OOM 记录会被覆盖。
- 权限问题:
dmesg默认需CAP_SYSLOG,普通用户常被拒;加sudo dmesg -w是最稳妥做法 - 缓冲区大小:
dmesg -l查看当前 buffer 大小(单位 KB),默认通常 16MB;OOM 日志本身不大,但若系统日志密集,几秒内就可能冲掉前一条;可通过sysctl -w kernel.dmesg_restrict=0(需 root)放宽限制,但不推荐长期开启 - 真正可靠的长期监控不是靠
dmesg -w手动盯屏,而是用exceptionbeat或自建脚本将dmesg -T | grep ...结果定期落盘 + 告警,否则人走茶凉,OOM 发生时你根本不在场











