文章主要介绍遇到OOM时,该怎么用jdk的bin目录下自带的jvisualvm.exe工具排查问题
拿到hprof文件
hprof文件是Java虚拟机生成的堆转储文件(Heap Profile的缩写),主要用于记录Java进程运行时的内存使用情况、对象实例信息及线程栈数据,帮助开发者分析内存泄漏、优化性能。
默认情况下是不会生成这个文件的,需要加一些特定的命令。
例如我新建了一个maven名为job-seach的项目,在该项目的com.polyang.job.search.jvm包下有个JvmMemoryDemo用来模拟OOM的情况
package com.polyang.job.search.jvm;
import java.util.HashMap;
import java.util.Map;
public class JvmMemoryDemo {
static class TestMemory {
byte[] b = new byte[1024*1024];
}
//声明缓存对象
private static final Map<String, Object> map = new HashMap<String, Object>();
public static void main(String[] args) {
//循环添加对象到缓存
for(int i = 0; i < 1000000; i++){
TestMemory t = new TestMemory();
map.put("key" + i, t);
}
}
}
然后在项目的根目录(pom.xml文件所在目录)允许以下命令,即可得到hprof文件
java -cp "target/classes" -Xms150m -Xmx150m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=E:/custom com.polyang.job.search.jvm.JvmMemoryDemo
用jvisualvm工具分析hprof文件
找到本地安装的JDK目录,进入bin目录,找到jvisualvm.exe文件,双击打开,然后可以看到以下界面
然后右上角点击“文件->装入”
在弹出的窗口中选择上面得到的hprof文件,然后你就会看到如下窗口
然后你就可以根据上面显示的信息排查问题了,比如这里,我点开“堆转储上的线程”就能看到具体OOM是发生在哪一行,如下图所示:
这是最简单也是最快速的方法。