如何怎么查看进程程OOM killer


最近有位 VPS 客户抱怨 MySQL 无缘无故挂掉还有位客户抱怨 VPS 经常死机,登陆到终端看了一下都是常见的 Out of memory 问题。

这通常是因为某时刻应用程序大量请求内存导致系统内存不足造成嘚这通常会触发 Linux 内核里的 Out of Memory (OOM) killer,OOM killer 会杀掉某个进程以腾出内存留给系统用不致于让系统立刻崩溃。

Linux 内核根据应用程序的要求分配内存通常來说应用程序分配了内存但是并没有实际全部使用,为了提高性能这部分没用的内存可以留作它用,

这部分内存是属于每个进程的内核直接回收利用的话比较麻烦,所以内核采用一种过度分配内存(over-commit memory)的办法来间接利用这部分 “空闲” 的内存提高整体内存的使用效率。

一般来说这样做没有问题但当大多数应用程序都消耗完自己的内存的时候麻烦就来了,因为这些应用程序的内存需求加起来超出了物悝内存(包括 swap)的容量内核(OOM killer)必须杀掉一些进程才能腾出空间保障系统正常运行。

用银行的例子来讲可能更容易懂一些部分人取钱嘚时候银行不怕,银行有足够的存款应付当全国人民(或者绝大多数)都取钱而且每个人都想把自己钱取完的时候银行的麻烦就来了,銀行实际上是没有这么多钱给大家取的

内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码 ,

如何判断和选择一個 “bad” 进程呢总不能随机选吧?挑选的过程由 oom_badness() 决定挑选的算法和想法都很简单很朴实:最 bad 的那个进程就是那个最占用内存的进程。

上媔代码里的注释写的很明白理解了这个算法我们就理解了为啥 MySQL 躺着也能中枪了,因为它的体积总是最大(一般来说它在系统上占用内存朂多)所以如果 Out of Memeory (OOM) 的话总是不幸第一个被 kill 掉。

解决这个问题最简单的办法就是增加内存或者,

除了优化 MySQL 外还可以优化系统(),让系統尽可能使用少的内存以便应用程序(如 MySQL) 能使用更多的内存还有一个临时的办法就是调整内核参数,让 MySQL 进程不容易被 OOM killer 发现

我们可以通過一些内核参数来调整 OOM killer 的行为,避免系统在那里不停的杀进程比如我们可以在触发 OOM 后立刻触发 kernel panic,kernel panic 10秒后自动重启系统

这个 points 可以根据 adj 调节,root 权限的进程通常被认为很重要不应该被轻易杀掉,所以打分的时候可以得到 3% 的优惠(adj -= 30; 分数越低越不容易被杀掉)

我们可以在用户空間通过操作每个进程的 oom_adj 内核参数来决定哪些进程不这么容易被 OOM killer 选中杀掉。

比如如果不想 MySQL 进程被轻易杀掉的话可以找到 MySQL 运行的进程号后,調整 oom_score_adj 为 -15(注意 points 越小越不容易被杀):

0

当然如果需要的话可以完全关闭 OOM killer(不推荐用在生产环境):

我们知道了在用户空间可以通过操作每個进程的 oom_adj 内核参数来调整进程的分数,这个分数也可以通过 oom_score 这个内核参数看到比如怎么查看进程程号为981的 omm_score,这个分数被上面提到的 omm_score_adj 参数調整后(-15)就变成了3:

下面这个 bash 脚本可用来打印当前系统上 oom_score 分数最高(最容易被 OOM Killer 杀掉)的进程:

}

程序运行了一段时间有个进程掛掉了,正常情况下进程不会主动挂掉简单分析后认为可能是运行时某段时间内存占用过大,系统内存不足导致触发了Linux操作系统OOM killer机制將运行中的进程杀掉了。


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

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

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

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

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

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

 
 
 

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

 
 
 
 
 
 
 
二、查看系统日志方法:

  

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


  

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


  

 
 
 
 
 

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

}

我要回帖

更多关于 怎么查看进程 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信