深入了解Linux OOM Killer:一次可怕的内核事件

发布时间:2024年01月12日

一、简介

The OOM Killer 是内核中的一个进程,当系统出现严重内存不足时,它就会启用自己的算法去选择某一个进程并杀掉. 之所以会发生这种情况,是因为Linux内核在给某个进程分配内存时,会比进程申请的内存多分配一些. 这是为了保证进程在真正使用的时候有足够的内存,因为进程在申请内存后并不一定立即使用,当真正使用的时候,可能部分内存已经被回收了. 比如 当一个进程申请2G内存时,内核可能会分配2.5G的内存给它.通常这不会导致什么问题.然而一旦系统内大量的进程在使用内存时,就会出现内存供不应求.很快就会导致内存耗尽. 这时就会触发这个oom killer,它会选择性的杀掉某个进程以保证系统能够正常运行。

二、OOM Killer

理解OOM Killer:

Linux 内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没有实际全部使用,为了提高性能,这部分没用的内存可以留作它用,这部分内存是属于每个进程的,内核直接回收利用的话比较麻烦,所以内核采用一种过度分配内存(over-commit memory)的办法来间接利用这部分 “空闲” 的内存,提高整体内存的使用效率。一般来说这样做没有问题,但当大多数应用程序都消耗完自己的内存的时候麻烦就来了,因为这些应用程序的内存需求加起来超出了物理内存(包括 swap)的容量,内核(OOM killer)必须杀掉一些进程才能腾出空间保障系统正常运行。用银行的例子来讲可能更容易懂一些,部分人取钱的时候银行不怕,银行有足够的存款应付,当全国人民(或者绝大多数)都取钱而且每个人都想把自己钱取完的时候银行的麻烦就来了,银行实际上是没有这么多钱给大家取的。

配置OOM Killer:

我们可以通过一些内核参数来调整 OOM killer 的行为,避免系统在那里不停的杀进程。

  1. Linux下每个进程都有个OOM权重,在/proc//oom_adj里面,取值是-17到+15,取值越高,越容易被干掉;

  2. linux内核会通过特定的算法给每个进程计算一个分数来决定杀哪个进程,每个进程的oom分数可以/proc/PID/oom_score中找到(分数越高,越容易被干掉);

  3. 我们可以通过调控每个进程的/proc//oom_adj来影响到每个进程的/proc/PID/oom_score;(正比例关系,oom_adj越大,oom_score分数越高,越容易被干掉)

当物理内存和交换空间都被用完时,如果还有进程来申请内存,内核将触发OOM killer,其行为如下:

1.检查文件/proc/sys/vm/panic_on_oom,如果里面的值为2,那么系统一定会触发panic
2.如果/proc/sys/vm/panic_on_oom的值为1,那么系统有可能触发panic(见后面的介绍)
3.如果/proc/sys/vm/panic_on_oom的值为0,或者上一步没有触发panic,那么内核继续检查文件/proc/sys/vm/oom_kill_allocating_task
3.如果/proc/sys/vm/oom_kill_allocating_task为1,那么内核将kill掉当前申请内存的进程
4.如果/proc/sys/vm/oom_kill_allocating_task为0,内核将检查每个进程的分数,分数最高的进程将被kill掉(见后面介绍)

进程被kill掉之后,如果/proc/sys/vm/oom_dump_tasks为1,且系统的rlimit中设置了core文件大小,将会由/proc/sys/kernel/core_pattern里面指定的程序生成core dump文件,这个文件里将包含pid, uid, tgid, vm size, rss, nr_ptes, nr_pmds, swapents, oom_score_adjscore, name等内容,拿到这个core文件之后,可以做一些分析,看为什么这个进程被选中kill掉。

这里可以看看ubuntu默认的配置:

#OOM后不panic
dev@ubuntu:~$ cat /proc/sys/vm/panic_on_oom
0

#OOM后kill掉分数最高的进程
dev@ubuntu:~$ cat /proc/sys/vm/oom_kill_allocating_task
0

#进程由于OOM被kill掉后将生成core dump文件
dev@ubuntu:~$ cat /proc/sys/vm/oom_dump_tasks
1

#默认max core file size是0, 所以系统不会生成core文件
dev@ubuntu:~$ prlimit|grep CORE CORE
max core file size 0 unlimited blocks

#core dump文件的生成交给了apport,相关的设置可以参考apport的资料
dev@ubuntu:~$ cat /proc/sys/kernel/core_pattern
|/usr/share/apport/apport %p %s %c %P

panic_on_oom

正如上面所介绍的那样,该文件的值可以取0/1/2,0是不触发panlic,2是一定触发panlic,如果为1的话就要看mempolicy和cpusets,这篇不介绍这方面的内容。

panic后内核的默认行
为是死在那里,目的是给开发人员一个连上去debug的机会。但对于大多数应用层开发人员来说没啥用,倒是希望它赶紧重启。为了让内核panic后重启,可以修改文件/proc/sys/kernel/panic,里面表示的是panic多少秒后系统将重启,这个文件的默认值是0,表示永远不重启。

#设置panic后3秒重启系统
dev@ubuntu:~$ sudo sh -c “echo 3 > /proc/sys/kernel/panic”

修改配置

上面的这些文件都可以通过下面三种方式来修改,这里以panic_on_oom为例做个示范:

直接写文件(重启后失效)

dev@ubuntu:~$ sudo sh -c “echo 2> /proc/sys/vm/panic_on_oom”

通过控制命令(重启后失效)

dev@dev:~$ sudo sysctl vm.panic_on_oom=2

修改配置文件(重启后继续生效)

#通过编辑器将vm.panic_on_oom=2添加到文件sysctl.conf中(如果已经存在,修改该配置项即可)
dev@dev:~$ sudo vim /etc/sysctl.conf

#重新加载sysctl.conf,使修改立即生效
dev@dev:~$ sudo sysctl -p

相关链接 深入了解Linux OOM Killer:一次可怕的内核事件

文章来源:https://blog.csdn.net/WatcherNight/article/details/135466443
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。