OOM Killer 先杀谁?读懂 Linux 内存不足时的自保逻辑

举报
yd_229284667 发表于 2026/11/08 17:24:51 2026/11/08
【摘要】 凌晨三点被告警吵醒,登录服务器一看,核心服务进程不见了,日志里只有一句:Out of memory: Killed process 12345 (java) ...这不是服务自己崩溃,而是 Linux 内核在内存耗尽时动了手:OOM Killer(内存溢出终结者)挑了一个进程杀掉,用来保住整个系统。本文把它的选择逻辑、复盘方法和预防手段一次讲清。 一、内存耗尽前,内核已经自救过两次OOM K...

凌晨三点被告警吵醒,登录服务器一看,核心服务进程不见了,日志里只有一句:

Out of memory: Killed process 12345 (java) ...

这不是服务自己崩溃,而是 Linux 内核在内存耗尽时动了手:OOM Killer(内存溢出终结者)挑了一个进程杀掉,用来保住整个系统。本文把它的选择逻辑、复盘方法和预防手段一次讲清。

一、内存耗尽前,内核已经自救过两次

OOM Killer 不是第一道防线。内存紧张时,内核会先做两件事:回收 page cache,把文件缓存腾出来;把不活跃的匿名内存换出到 swap。只有这两招都顶不住、available 内存见底时,才会轮到 OOM Killer。

所以看内存不能只看 free 那一行的 used。free -m 里真正要紧的是 available:它表示还能分给新进程的内存。cache 占得再高也不必慌,那是可回收的;available 持续走低、swap 也被用满,才是真正的危险信号。很多“内存满了”的误报,都是把 cache 当成了泄漏。

二、OOM Killer 按什么标准挑“牺牲者”

每个进程在内核里都有一个分数,可以直接查看:

cat /proc/<pid>/oom_score

分数越高,越先被杀。打分大致遵循三条规则:占用的内存越多,分越高;进程的子进程越多,牵连的分也越高;运行时间越长、越重要的系统进程,分会相对低一些。root 用户运行的进程通常也会得到一点优待,但这只是倾向,不是免死金牌。

真正的“免死金牌”是 oom_score_adj,取值范围是 -1000 到 1000:

echo -500 > /proc/<pid>/oom_score_adj

-1000 表示永不被杀,数值越大越容易被选上。生产上常见的做法,是给 sshd、监控 agent 这类“救命”进程调低分数,给可以重启的无状态 worker 调高分数。但要注意,-1000 不要随便用:被保护的进程如果真的泄漏,内核杀不掉它,就会去杀别的进程,最终可能连系统都保不住。

三、事后复盘:三条命令找到“凶手”

服务被杀后,先别急着重启,用这三条命令把现场留存下来:

dmesg -T | grep -i "out of memory"
journalctl -k -b | grep -i oom
grep -E "MemTotal|MemAvailable|SwapTotal|SwapFree" /proc/meminfo

dmesg 会记录被杀进程的名字、PID、当时占用的内存,以及触发时的内存水位。结合应用自己的日志,就能判断是某个接口突发大流量撑爆了内存,还是慢泄漏积累了几天终于越线。前者要限流、要降级,后者要修代码,两者的解法完全不同。

四、预防:让它“死得明白,活得更久”

最有效的预防,是在 OOM Killer 动手之前给进程画好边界。用 systemd 管理服务时,可以直接限制内存:

[Service]
MemoryMax=2G
MemoryHigh=1.5G

超过 MemoryHigh 会先被节流,超过 MemoryMax 进程会被 systemd 结束,现场干净、原因明确,比等内核随机挑一个进程杀掉要可控得多。Java、Go 这类运行时也要记得显式限制堆大小,不要让堆跟着机器内存一起“自由生长”。

另外两件事同样重要:给 available 内存设告警阈值,比如低于总内存的 10% 就告警,留出处理时间;上线前做一次内存压测,确认峰值流量下内存曲线的形状,而不是等半夜被告警叫醒。

OOM Killer 不是敌人,它是内核在极端情况下的最后一道保险。理解它的打分规则、留好复盘证据、提前设好上限,下一次内存告警来的时候,你就不用再靠猜来定位问题了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。