我们在处理线上问题的时候,如果遇到了程序进程突然被kill掉,可以通过下面的命令来查看程序死掉的时间:
#查看oom被kill的进程
grep "Out of memory" /var/log/messages
或者:
#查看系统日志:
egrep -i -r 'killed process' /var/log
或者:
dmesg -T| grep java
从这些日志中我们可以看到程序oom的时间,结合我们程序本身的日志,可以推算是否是自己的程序挂掉了。
一般java程序在部署的时候会在启动的脚本中加入dump信息来帮助我们迅速定位线上的问题。
例如我写个简单的程序:
public class Main {
public static void main(String[] args) {
List<byte[]> list = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
list.add(new byte[1024000]);
}
}
}
只要程序一运行我们很快就会发现OOM异常:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at com.xqnode.Main.main(Main.java:10)
从这个异常中我们会快速定位到具体的哪一行出了问题。但是在实际生产环境不会出现这么简单的代码,通常程序是在不同的包中相互调用,而且会有多线程的情况,比较难定位到具体的错误发生的代码,所以我们在启动脚本中加入dump信息,然后我们就能找到对应的问题所在了。这里我们制定dump文件输出到D盘下。
启动配置:
再次运行程序,出现OOM的时候会在D盘下看到这个文件:
然后我们使用jdk中自带的工具jvisualvm.exe打开dump文件,路径在jdk/bin下。
点击 文件 => 装入,选择后缀名,打开文件
看到的界面如下:
我们从上面的红色部分可以清晰的看到我们的程序错误在哪里。
还可以使用jmap对正在进行的程序进行分析:
jmap -dump:live,format=b,file=heap.bin <pid>