记录一次应用被突然kill掉的问题定位经历

记录一次应用被突然kill掉的问题定位经历

问题背景:一次启动本地应用,两分钟过后自动退出,通过日志并未发现任何异常状况,莫名其妙的应用就自动被杀掉了;

解决思路:

1、linux通过top查看java应用内存和cpu都不高,只是过一会突然就没了;

2、通过应用日志并未查到有任何异样,代码也走查了好几遍;

3、通过dmesg | grep java查看内核日志信息,发现了问题所在,如下:

代码语言:javascript代码运行次数:0运行复制[16949523.941194] java invoked oom-killer: gfp_mask=0xd0, order=0, oom_score_adj=991

[16949523.942914] java cpuset=73a35980233979bb67f20700c76d77805de6ced7cfd18de836238a7bdae7c1dd mems_allowed=0

[16949523.942918] CPU: 4 PID: 310033 Comm: java Tainted: G U O 3.10.107-1-tlinux2_kvm_guest-0052 #1

[16949523.971234] Memory cgroup out of memory: Kill process 310033 (java) score 1964 or sacrifice child

[16949523.973103] Killed process 182650 (java) total-vm:16705124kB, anon-rss:2079844kB, file-rss:22020kB以上信息可以看到内存溢出被linux杀掉的java应用信息;

4、但是我应用内存占用并不是特别高,通过jinfo -flags 发现java应用的启动预申请内存达到了10G;

启动参数5、通过free或者vmstat查看剩余内存大小只有10G了,内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码 linux/mm/oom_kill.c,当系统内存不足的时候,out_of_memory() 被触发,然后调用 select_bad_process() 选择一个 “bad” 进程杀掉,如何判断和选择一个 “bad” 进程呢,总不能随机选吧?挑选的过程由 oom_badness() 决定,挑选的算法和想法都很简单很朴实:最 bad 的那个进程就是那个最占用内存的进程。

6、oom_kill.c 代码里可以看到 oom_badness() 给每个进程打分,根据 points 的高低来决定杀哪个进程,这个 points 可以根据 adj 调节,root 权限的进程通常被认为很重要,不应该被轻易杀掉,所以打分的时候可以得到 3% 的优惠(adj -= 30; 分数越低越不容易被杀掉)。我们可以在用户空间通过操作每个进程的 oom_adj 内核参数来决定哪些进程不这么容易被 OOM killer 选中杀掉。比如,如果不想 MySQL 进程被轻易杀掉的话可以找到 MySQL 运行的进程号后,调整 oom_score_adj 为 -15(注意 points 越小越不容易被杀)

7、oom_score_adj设置值范围-1000 到 1000范围区间,设置举例:当某一个应用内存申请占用1G时,设置oom_score_adj=-500时,实际linux会认为该应用只用了500M,会有个打折机制;以确保某些重要应用不会被意外kill掉;

相关推荐

区划-深圳政府在线
365bet足彩官网

区划-深圳政府在线

📅 08-05 👁️ 5694
下载与解析GFS气象数据:从互联网获取全球气象预报
解读女性阴道内温度升高的原因及应对措施
英国365老板

解读女性阴道内温度升高的原因及应对措施

📅 07-30 👁️ 4749