39

Linux 内核 OOM killer 机制

 4 years ago
source link: https://www.tuicool.com/articles/rmU7riF
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

有时候,我们会碰到程序正常运行了一段时间后有个进程挂掉了,正常情况下进程不会主动挂掉,这种情况有可能是运行时某段时间内存占用过大,系统内存不足导致触发了Linux操作系统OOM killer机制,将运行中的进程杀掉了。

一、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的那个进程就是那个最占用内存的进程。

【0】什么时候触发?

内核在触发OOM机制时会调用到 out_of_memory() 函数,此函数的调用顺序如下:

以上函数 __alloc_pages_may_oom() 在调用之前会先判断 oom_killer_disabled 的值,如果有值,则不会触发OOM机制;

布尔型变量 oom_killer_disabled 定义在文件mm/page_alloc.c中,并没有提供外部接口更改此值,但是在内核中此值默认为 0 ,表示打开OOM-kill。

Linux中内存都是以页的形式管理的,所以不管是怎么申请内存,都会调用 alloc_page() 函数,最终调用到函数 out_of_memory() ,触发OOM机制。

【1】内核监测到系统内存不足时,该函数被触发执行:

【2】选择一个“最坏的”进程

【3】杀掉进程

二、查看系统日志方法:

运行 egrep-i-r'killed process'/var/log 命令,结果如下:

也可运行 dmesg 命令,结果如下:

显示可读时间的话可用 dmesg-T 查看:

三、附加代码

下面附加两个函数是 select_bad_process() 函数的实现细节,可选看。

最后,简单分析一下你的进程被Linux杀掉几个可能的原因:一种是内存泄露;一种是你的进程所需要的内存资源太大,系统无法满足,应该在设计时对进程需要的资源有个最大限制,不能让他无限增长;当然,也不一定全是你的问题,也有可能是同一主机的其他进程占用资源过多,但是Linux OOM选择“最坏“进程杀掉的算法是很简单粗暴的,就选中你的进程杀掉,也是有可能的。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK