# 前言
前两天部署了一个java程序在服务器,服务器是2核2G的,但每次部署后
持续一段时间后,会无故进程停止了,没有任何日志记录,查看业务日志,java进程是正常退出的
也通过添加JVM一些启动参数来生成错误日志以及堆转储日志,都没有发现问题
考虑到服务器内存较小,不知道是不是这个原因
# 可能导致进程被杀掉的情况
- 内存泄漏;
- 进程所需的内存资源太大,对于 java 进程而言,除了 - Xmx 设置最大堆大小,还需要考虑元数据空间、堆外内存、直接内存的使用;
- 其他进程需要占用较多的资源,但是被 OOM Killer 机制选中当前进程;
经过排查发现,是因为系统内存资源紧张,被系统选中杀死
# 主要介绍 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的那个进程就是那个最占用内存的进程。
# 怎么避免 OOM Killer 误杀我的业务进程?
避免 oom killer 的方案
- 直接修改 /proc//oom_score_adj 文件,将其置为 - 1000
以前是通过/proc//oom_score来控制的,但近年来新版linux已经使用oom_score_adj来代替旧版的oom_score
- 直接关闭
关闭
echo "0" > /proc/sys/vm/oom-kill
激活
echo "1″ > /proc/sys/vm/oom-kill