记一次程序莫名killed的排查过程

1.场景描述

这几天在某个项目上出现应用莫名被down掉的情况,且没有明确报错信息。针对这种情况,我们进行排查发现

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是将占用内存最多的应用直接kill掉。

2.日志判断

我们可以通过查看系统日志判断是否由于OOM killer导致应用被kill,系统日志文件地址:/var/log/messages

我们可以直接在此目录下进行对应日志查看,也可以通过grep "Out of memory" /var/log/messages 进行快速查看。示例:


根据示例可看到,0点55时由于内存不足导致触发了OOM killer。

3.解决方式

3.1.降低应用的内存使用情况。

除优化代码外,可以通过启动的jar的时候增加-Xmsxxm -Xmxxxm的方式限定jvm大小,达到节约内存的作用(jvm大小根据程序的具体情况而定)。

nohup java -jar -Xms256m -Xmx512m xxx.jar >/dev/null &

若不指定jvm大小,最大对内存一般默认为物理内存的1/4,最小堆内存一般默认为物理内存的1/64。这容易导致本身不怎么耗内存的应用,因为jvm特别大,导致gc不频繁(minorGC),将会占用大量不必要的内存。

3.2 设置swap分区

swap分区含义:当系统的物理内存不够用的时候,就需要将物理内存中的一部分空间释放出来,以供当前运行的程序使用。那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到swap空间中。一般推荐大小为物理内存的2倍。

所以可以认为swap类似于虚拟内存,当内存不存的时候,可以充当内存。但是由于swap分区一般都是磁盘,所以性能肯定比物理内存差。但是针对无法扩容或存在大量定时计算的情况,可以考虑使用swap的方式在增大内存,避免OOM killer。

扩容完成或swap足够大,我们需要进行swap使用频率的设置,命令如下:

#vm.swappiness=频率,swappiness=0的时候表示最大限度使用物理内存,然后才是 swap空间,swappiness=100的时候表示积极的使用swap分区,并且把内存上的数据及时的搬运到swap空间里面。你的内存在使用到(100-频率)%的时候,就开始出现有交换分区的使用。这样子会加大系统io,同时造的成大量页的换进换出,严重影响系统的性能.所以建议swap分区设置为10

sysctl vm.swappiness=10 

#查看当前swap的使用频率

cat /proc/sys/vm/swappiness

你可能感兴趣的:(记一次程序莫名killed的排查过程)