最近在linux开发日常中,维护之前发布的程序,几台服务器只有一台在重启,而且不定期,查看服务日志也没有任何signal信号以及服务挂掉的原因打印,迫于无奈怀疑是linux系统给服务干掉了。于是想查看服务被杀掉的日志,看看系统日志,即可判断。
即途中目录下的messages文件,通过命令即可过滤信息查看是否被系统killed。
用以下命令查看系统日志信息!
egrep -i 'killed process' /var/log/messages
命令输出如下:
参数解析:
total-vm: total virtual memory. 进程使用的总的虚拟内存。
rss: resident set size. 驻留集大小。驻留集是指进程已装入内存的页面的集合。
anon-rss: anonymous rss. 匿名驻留集。比如malloc出来的就是匿名的。
file-rss: 映射到设备和文件上的内存页面。
shmem-rss: 大概是shared memory rss?
从上述输出可以看出被系统杀掉了!时间也能对上,9点52分被杀掉,至此已经排查出问题,就是服务器内存不够用所导致!!!准备修改这台服务器的服务权重,尽量少分配任务来减小这台服务器压力。
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的那个进程就是那个最占用内存的进程。
基本概念
Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀掉。
oom killer机制分析
oom killer是计算出选择哪个进程kill呢?我们先来看一下kernel提供给用户态的/proc下的一些参数: /proc/[pid]/oom_adj ,该pid进程被oom killer杀掉的权重,介于 [-17,15]之间,越高的权重,意味着更可能被oom killer选中,-17表示禁止被kill掉。 /proc/[pid]/oom_score,当前该pid进程的被kill的分数,越高的分数意味着越可能被kill,这个数值是根据oom_adj运算后的结果,是oom_killer的主要参考。
sysctl 下有2个可配置选项:
- vm.panic_on_oom = 0 #内存不够时内核是否直接panic
- vm.oom_kill_allocating_task = 1 #oom-killer是否选择当前正在申请内存的进程进行kil
- 如果想修改被oom killer选中的概率,禁止或者给oom_adj最小或偏小的值,也可以通过sysctl调节oom killer行为
可以保护重要的进程不被OOM Killer干掉吗?还真是可以!
OOM Killer会检查 /proc/$pid/oom_score_adj文件来调整最终的分数 (oom_score)。所以我们可以通过在这个文件中给一个大的负数,以降低该进程被选中并终止的可能性。oom_score_adj可以在-1000到1000间变化。如果你给了-1000,进程即使使用了100%的内存也不会被OOM Killer干掉。可通过下面命令修改oom_score_adj(比如设为-200):