Linux 保护进程不被OOM Killer

From: https://blog.csdn.net/flysqrlboy/article/details/89011635

最近在预发环境上有一个重要的进程隔三差五就被OOM Killer干掉(通过查看CentOS系统日志/var/log/messages揪出来是OOM Killer干的)。该机器上跑着各种进程,内存是有些吃紧。这当然可以通过加大机器内存或者迁走某些进程来解决。但一时又没有多余的机器和内存资源,只能自己动手丰衣足食了(资源短缺确实是更能激发人去思考更优更节省的方案)。现在我要解决的是如下两个问题:

为什么被OOM Killer干掉的是这个进程而不是其他的?
能保护某个进程不被OOM Killer 干掉吗?
Surviving the Linux OOM Killer》一文正是对上面两个问题的介绍。

基本概念:

Linux 内核有个机制叫OOM killer(Out Of Memory killer),该机制会监控那些占用内存过大,尤其是瞬间占用内存很快的进程,然后防止内存耗尽而自动把该进程杀掉。内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码linux/mm/oom_kill.c,当系统内存不足的时候,out_of_memory()被触发,然后调用select_bad_process()选择一个”bad”进程杀掉。如何判断和选择一个”bad进程呢?linux选择”bad”进程是通过调用oom_badness(),挑选的算法和想法都很简单很朴实:最bad的那个进程就是那个最占用内存的进程。

如何查看:

grep "Out of memory" /var/log/messages

查看系统日志方法:

运行egrep -i -r ‘killed process’ /var/log命令, 也可运行dmesg命令

sudo dmesg -T | grep "(java)" 

How does OOM Killer choose which process to kill?

Linux 内核会给每个运行中的进程分配一个叫 oom_score 的分数,它表示当系统可用内存很低时,一个进程被kill掉的可能性有多大。分数越高,越有可能被kill掉。分数值很简单:等于进程的内存占用百分比乘以10。比如一个进程占50%的内存,它的oom_score值就是 50 X 10 = 500 .
一个进程的oom_score被记录在/proc/$pid/oom_score 文件中。

Can I ensure some important processes do not get killed by OOM Killer?

OOM Killer会检查 /proc/$pid/oom_score_adj文件来调整最终的分数 (oom_score)。所以我们可以通过在这个文件中给一个大的负数,以降低该进程被选中并终止的可能性。oom_score_adj可以在-1000到1000间变化。如果你给了-1000,进程即使使用了100%的内存也不会被OOM Killer干掉。可通过下面命令修改oom_score_adj(比如设为-200):

sudo echo -200 > /proc/$pid/oom_score_adj

或者,我们可以:

echo -17 > /proc/<pid>/oom_adj

-17表示禁用OOM我们也可以对把整个系统的OOM给禁用掉:

sysctl -w vm.panic_on_oom=1sysctl -p

参数/proc/sys/vm/overcommit_memory可以控制进程对内存过量使用的应对策略
当overcommit_memory=0 允许进程轻微过量使用内存,但对于大量过载请求则不允许
当overcommit_memory=1 永远允许进程overcommit

当overcommit_memory=2 永远禁止overcommit

版权声明:本文为CSDN博主「keke_xin」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/keke_Xin/article/details/84829816

Caveats of adjusting OOM scores

警告:解决内存不足的最好办法还是增加可用内存(例如更好的硬件)或者将某些进程移到别的地方去,又或者优化代码以减少内存消耗。

oom killer理解和日志分析:知识储备

oom killer理解和日志分析:日志分析