突然消失的Java进程
一、背景说明
在一次大批量数据测试时,一个Java服务模块突然宕掉,并且连续出现了好几次。检查服务已经开启了打印堆栈信息-XX:+HeapDumpOnOutOfMemoryError
,
但是在服务器运行目录下并没有发现.hprof文件生成。服务器总内存为16G,当前Java服务设置的内存为:-Xms5000M -Xmx8000M
。
二、原因分析
Java进程突然被干掉无外乎以下三种情况:
- Linux OOM killer 杀死了Java进程
- JVM自身故障
- JVM OOM导致进程退出
2.1 Linux 的OOM killer
Linux内核有一个OOM(out of memory) killer机制,当系统内存严重不足时,OOM killer会选择一个或多个进程杀死。关于OOM killer机制可参考上一篇文章Linux中的CommitLimit与OOM Killer.。
因此,当java进程突然消失时,首先怀疑是不是被OOM killer杀掉了。
查看系统日志文件
/var/log/messages
$egrep -i 'killed process' /var/log/messages
Nov 19 16:24:31 localhost kernel: Killed process 26980 (java) total-vm:14316628kB, anon-rss:6138236kB, file-rss:0kB, shmem-rss:0kB
查看linux系统内核日志
$dmesg | grep java
[3571149.337671] Out of memory: Kill process 26980 (java) score 243 or sacrifice child
[3571149.338458] Killed process 26980 (java) total-vm:14316628kB, anon-rss:6138236kB, file-rss:0kB, shmem-rss:0kB
[3571149.395860] java: page allocation failure: order:0, mode:0x201da
[3571149.395864] CPU: 0 PID: 26980 Comm: java Kdump: loaded Tainted: G L ------------ T 3.10.0-957.el7.x86_64 #1
2.2 JVM的自身故障
当JVM发生致命错误导致崩溃时,会生成一个hs_err_pid_xxx.log这样的文件,该文件包含了导致 JVM crash 的重要信息,我们可以通过分析该文件定位到导致 JVM Crash 的原因,从而修复保证系统稳定。
默认情况下,该文件是生成在工作目录下的,当然也可以通过 JVM 参数指定生成路径:
-XX:ErrorFile=/var/log/hs_err_pid<pid>.log
这个文件主要包含如下内容:
- 日志头文件
- 导致 crash 的线程信息
- 所有线程信息
- 安全点和锁信息
- 堆信息
- 本地代码缓存
- 编译事件
- gc 相关记录
- jvm 内存映射
- jvm 启动参数
- 服务器信息
2.3 JVM的OOM
JVM由于有GC机制,一般很少发生OOM,但是如果出现内存泄露,就可能发生OOM导致java进程退出。
可以根据JVM的下面两个参数查找堆内存快照文件定位问题。
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=*/java.hprof
找到dump快照文件,借助一些MAT或VisualVM这一类可视化工具分析问题原因。
三、总结
当java进程突然消失时,可以先查看是否有dump文件;如果没有dump文件,再查看是否有hs_err_pid.log日志;如果也没有,则查看内核日志。
参考文章
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 逐光の博客!
评论