文档首页> 技术教程> 进程莫名消失:OOM Killer 的证据链

进程莫名消失:OOM Killer 的证据链

发布时间:2026-02-12 13:45        更新时间:2026-02-13 05:48
应用日志里没有报错、代码里没有退出逻辑,进程却不见了——大概率是被内核的 OOM Killer(内存耗尽保护机制)杀掉的,证据在内核日志里。 怎么找证据 内存耗尽时内核会留下明确记录,两条命令任选: dmesg -T | grep -i "out of memory" journalctl -k | grep -iE "oom|killed process" 看到"Out of memory: Killed process 12345 (java)"这样的行就是实锤,记录里有时间戳,后面还跟着当时各进程的内存占用表,照着表里 RSS 最大的进程查,基本就是元凶。老系统上 /var/log/messages(CentOS)或 /var/log/syslog(Ubuntu)里也有同样内容。记录的时间戳精确到秒,拿它和应用日志的最后一行对一下,进程是哪一秒没了动静,两边能严丝合缝地接上。 还原事发曲线 想看事发前的内存走势,装了 atop 的机器有现成历史:/var/log/atop/ 下每天一个文件,atop -r /var/log/atop/atop_日期 可以回放当天的采样,OOM 之前是谁把内存推上去的一目了然。没有 atop,监控平台的内存趋势图也能粗略还原时间线。 score 机制是什么 内核给每个进程算一个 oom_score,占内存越多分越高,触发保护时杀分最高的,不认主次。所以常见 java、mysqld 被杀——它们恰好是内存大户,连累它们的其实是整机紧张。cat /proc/PID/oom_score 可以查单个进程当前的得分。 怎么预防 按优先级做三件事:一是控量,数据库设 buffer pool 上限、JVM 设堆上限,应用峰值留出余量;二是保命,对核心进程降权,echo -1000 > /proc/PID/oom_score_adj,用 systemd 管理的就写 OOMScoreAdjust=-1000;三是预警,监控加"可用内存低于一成半告警",比事后验尸有用。还有个朴素的动作:给每台机器写清内存预算,系统、数据库、应用各占多少,加起来不超过总量八成,超售从源头上就少发生。内核默认允许内存超售(overcommit),严格模式 vm.overcommit_memory=2 能提前拒绝不合理的申请,但配置不当会误伤业务,一般机器先靠限额加告警,不轻易上这个硬开关。 最后提醒:OOM 是结果不是原因,顺着内核记录找到把内存吃光的那个进程,才算真正查完。