java后端服务因触发OOM机制异常停止问题解决方案
(2019-10-29 19:12:24)分类: JAVA异常汇总 |
问题现象:
linux服务器上的datamanager后端服务、reportmanager后端服务运行两三天之后就异常停止了。
问题原因排查:
1、排查后端服务的启动日志和log日志,没有任何异常信息记录,确认异常停止原因不是后端服务自身导致;
2、排查linux系统的history操作日志,确认不是由其他同事停止了后端服务;
3、通过 dmesg |grep java命令,确认后端服务是因Out of memory被系统强制kill掉。
下面是命令执行结果:
[root@zcdq-bi backend]# ps -ef | grep java
root
root
root
root
[root@zcdq-bi backend]# ^C
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]#
[root@zcdq-bi backend]# dmesg |grep java
[23497833.885078] [63367]
[23497833.885080] [65939]
[23497833.885093] [86388]
[23497833.885095] Out of memory: Kill process 65939 ( score 104 or sacrifice child
[23497833.885311] Killed process 65939 ( total-vm:10069836kB, anon-rss:1750868kB, file-rss:0kB
[23498248.708062] java invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
[23498248.708068] java cpuset=/ mems_allowed=0
[23498248.708071] CPU: 7 PID: 86898 Comm: java Tainted: G
[23498248.708332] [63367]
[23498248.708351] [86388]
[23498248.708353] [86882]
[23498248.708356] Out of memory: Kill process 86882 ( score 103 or sacrifice child
[23498248.708604] Killed process 86882 ( total-vm:9029068kB, anon-rss:1733124kB, file-rss:0kB
[23500812.639653] [63367]
[23500812.639670] [86388]
[23500812.639706] [89654]
[23500812.639711] Out of memory: Kill process 86388 ( score 100 or sacrifice child
[23500812.639965] Killed process
86388
( total-vm:10038812kB, anon-rss:1679036kB, file-rss:0kB
后端服务Out of memory原因:
首先查看系统内存使用情况,发现可用内存只有1569M,其中有10G的buff和cache,在这种情况下启动两个后端服务,会将可用内存减少到700M,此时会触发Linux内核的OOM killer(Out-of-Memory killer)机制,该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽,内核会把该进程杀掉(通过 dmesg |grep java命令确认)。
[root@zcdq-bi backend]# free -m
Mem:
Swap:
问题解决方案:
Step1:清除系统的buff和cache
仅清除页面缓存(PageCache)
shell命令:
清除目录项和inode
shell命令:
清除页面缓存,目录项和inode
shell命令:
Step2:后端服务启动限制内存使用
服务启动命令中添加-Xmx512m 参数限制内存使用
nohup
Step3:禁止后端服务触发OOM机制
Linux内核会通过特定的算法给每个进程计算一个分数来决定杀哪个进程,每个进程的OOM分数可以在/proc/进程号/oom_score中找到。
可以通过下面这条命令为该进程禁用OOM机制:
echo -17>/proc/进程号/oom_adj
oom_adj的可调值为15到-16,其中15最大,-16最小,-17为禁止使用OOM。
备注:oom_score为2的n此房计算出来的,其中n就是进程的oom_adj值,所以oom_score的分数越高就越会被内核优先杀掉。