发布于 2026-01-06 0 阅读
0

如何应对 Linux OOM Killer

如何应对 Linux OOM Killer

当您的 Linux 系统内存不足时,内核会调用内存溢出 (OOM) killer来释放内存。这种情况经常发生在运行大量内存密集型进程的服务器上。本文将深入探讨 OOM killer 何时被调用、它如何决定终止哪个进程,以及我们是否可以阻止它终止数据库等重要进程。

OOM Killer 如何选择要终止的进程?

Linux 内核会给每个运行中的进程分配一个 oom_score 分数,oom_score该分数表示在可用内存不足的情况下进程被终止的可能性。该分数与进程使用的内存量成正比。分数计算公式10 x percent of memory used by process为 100% × 10⁻⁵ = 1000。因此,最高分数为 100% × 10⁻⁵ = 1000。此外,如果进程以特权用户身份运行,则其oom_score 分数会比普通用户进程在相同内存使用量下略低。在早期版本的 Linux(内核版本 2.6.32)中,使用了一种更为复杂的启发式方法来计算此分数。

进程的得分oom_score可以在目录中找到/proc。假设你的进程的进程 ID (pid) 为 42,cat /proc/42/oom_score那么该进程的得分就会显示出来。

如何确保某些重要进程不会被OOM Killer终止?

是的!OOM killer 会检查oom_score_adj并调整其最终计算出的分数。该文件位于 [此处应填写/proc/$pid/oom_score_adj文件路径]。您可以向该文件添加一个较大的负分,以确保您的进程被 OOM killer 选中并终止的概率更低。该值oom_score_adj可以在 -1000 到 1000 之间变化。如果您将其设置为 -1000,即使进程使用 100% 的内存,它仍然可以避免被 OOM killer 终止。另一方面,如果您将其设置为 1000,即使进程仅使用极少的内存,Linux 内核也会不断终止该进程。

让我们回到进程 ID 为 42 的进程。以下是如何更改其参数的方法oom_score_adj

echo -200 | sudo tee - /proc/42/oom_score_adj
Enter fullscreen mode Exit fullscreen mode

我们需要以root普通用户身份执行此操作,sudo因为 Linux 不允许普通用户降低 OOM 分数。您可以以普通用户身份增加 OOM 分数,无需任何特殊权限。例如:echo 100 > /proc/42/oom_score_adj

还有另一个粒度较粗的评分,称为,oom_adj其取值范围为 -16 到 15。它与类似oom_score_adj。实际上,当您设置时oom_score_adj,内核会自动缩小其范围并计算oom_adjoom_adj有一个神奇的值为 -17,表示给定的进程永远不应该被 OOM killer 终止。

显示所有正在运行的进程的 OOM 分数

此脚本按 OOM 分数降序显示所有运行进程的 OOM 分数和 OOM 调整分数。


#!/bin/bash
# Displays running processes in descending order of OOM score
printf 'PID\tOOM Score\tOOM Adj\tCommand\n'
while read -r pid comm; do [ -f /proc/$pid/oom_score ] && [ $(cat /proc/$pid/oom_score) != 0 ] && printf '%d\t%d\t\t%d\t%s\n' "$pid" "$(cat /proc/$pid/oom_score)" "$(cat /proc/$pid/oom_score_adj)" "$comm"; done < <(ps -e -o pid= -o comm=) | sort -k 2nr
Enter fullscreen mode Exit fullscreen mode

检查是否有任何进程因内存不足而被终止。

最简单的方法是查看grep系统日志。在 Ubuntu 系统中:grep -i kill /var/log/syslog。如果某个进程被终止,您可能会看到类似这样的结果。my_process invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0

调整 OOM 分数的注意事项

请记住,内存溢出 (OOM) 是更大问题的征兆——可用内存不足。解决此问题的最佳方法是增加可用内存(例如,升级硬件)、将部分程序迁移到其他机器或减少程序的内存消耗(例如,尽可能减少分配的内存)。

对 OOM 调整分数进行过多调整会导致随机进程被终止,并且无法释放足够的内存。

参考

  1. proc手册页
  2. https://askubuntu.com/questions/60672/how-do-i-use-oom-score-adj/
  3. 逐步讲解Linux 代码的哪一部分被调用
  4. 经典的LWN文章(有点过时了)
  5. 手动调用 OOM killer
文章来源:https://dev.to/rrampage/surviving-the-linux-oom-killer-2ki9