关注微信公众号:程序猿的日常分享,定期更新分享。
背景
在日常使用中,用一段时间后突然发现服务找不到了抛出异常:HSFServiceAddressNotFoundException,通过排查日志,没有发现oom的日志,并且也没有发现OOM生成的java.hprof文件。
排除了虚拟机oom的情况后,那么问题就剩下了进程被操作系统或用户kill了。
于是查看/var/log/messages
果然,发现java进程被Linux OOM kill了,再查看dmesg,进一步得到了确认
image.png
到这里,真相开始揭晓,Java进程是由于linux oom score的分数太高,被kill了。
查看机器内存:2c4g
发现有一个地方判断机器内存大于2G就设置成4G,大坑
显而易见,随着使用过程中jvm内存的累积,加上其他进程使用内存,可能还没触发GC就被linux kill了
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的那个进程就是那个最占用内存的进程。
通常会在下面条件下触发Linux OOM:1、 VM里面分配不出更多的page。2、 用户地址空间不足。
关注微信公众号:程序猿的日常分享,定期更新分享。
网友评论