故障排查:java应用启动后进程自动被杀
java项目部署以后,过一段时间发现进程已不存在,
启动java项目命令如下,启动日志写入当前目录下的nohup.out文件:
# nohup java -jar server-0.0.1-SNAPSHOT.jar &
[6] 118424
# nohup: ignoring input and appending output to ‘nohup.out’
查看进程存在:
# ps -ef |grep server-0.0.1-SNAPSHOT.jar
root 118424 1 1 15:20 pts/1 00:00:56 java -jar /data/workspace/server-0.0.1-SNAPSHOT.jar
查看项目占用的端口是否正常在监听:
# netstat -tulnp|grep 8084
tcp6 0 0 :::8084 :::* LISTEN 118424/java
一段时间后进程不存在了,查看项目日志未发现报错或异常;
于是,查看系统日志:
# tail -f /var/log/messages
Mar 1 15:14:08 s6 kernel: [124232] 0 124232 28177 61 12 0 0 grep
Mar 1 15:14:08 s6 kernel: Out of memory: Kill process 118430 (java) score 78 or sacrifice child
Mar 1 15:14:08 s6 kernel: Killed process 118430 (java) total-vm:5745276kB, anon-rss:978344kB, file-rss:1140kB, shmem-rss:0kB
Mar 1 15:17:12 s6 clamd[12450]: SelfCheck: Database status OK.
发现是因为内存溢出!
于是手动杀掉暂时未使用的进程,比如微服务的应用,是服务器内存空闲出一部分,重新启动server-0.0.1-SNAPSHOT.jar应用,恢复正常,进程没有再自动挂掉了。
理论解释:
操作系统(operating system)构建在进程(process)的基础上, 进程由内核作业(kernel jobs)进行调度和维护,其中有一个内核作业称为 “Out of memory killer(OOM终结者)”,Out of memory killer 在可用内存极低的情况下会杀死某些进程。只要达到触发条件就会激活,选中某个进程并杀掉。 通常采用启发式算法,对所有进程计算评分(heuristics scoring),得分最低的进程将被 kill 掉。 Out of memory: Kill process or sacrifice child 既不由JVM触发,也不由JVM代理,而是系统内核内置的一种安全保护措施。如果可用内存(含swap)不足, 就有可能会影响系统稳定,这时候 Out of memory killer 就会设法找出流氓进程并杀死他,也就是引起 Out of memory: kill process or sacrifice child 错误。