JVM:使用 MAT 工具结合jmap命令分析内存泄漏
1、下载MAT工具
2、演示内存溢出
- 新建一个springboot项目,新建一个controller
@RestController
public class HeapControler {
private ArrayList<User> arrayList = new ArrayList<User>();
@GetMapping("/heapmmo")
public void heapDemo(){
while (true) { //死循环导致内存溢出
arrayList.add(new User("213","231"));
}
}
}
- 修改虚拟机 vm,添加 -Xmx32M -Xms32M
- 运行springboot项目,访问 http://localhost:8080/heapmmo
3、使用 jmap 导出内存映像文件
-
打开cmd,进入桌面
-
执行命令
jps
,查看springboot项目的进程号 -
可以发现springboot进程号是 14036,执行命令
jmap -dump:format=b,file=a.hprof 14036
-
桌面会生成一个 a.hprof 的文件
4、使用 MAT 打开,File —> open file —> a.hprof
可以发现可能导致的问题有两个,然后分析这两个问题:
首先第一个,点击 details
通过第3行,基本上能够定位到我们的 controller。
- 另外,我们可以点击左上角第二个图标,通过对象数量定位异常
在第一行输入匹配规则,我们匹配我们自己的项目 com.eaphy ,可以看出User类的数量达到了46万多个,肯定是不正常的。
然后,右键User,找到是哪个GC Roots引用了该对象
可以清楚的看到,是HeapControler 里面的 arraylist。
- 另外,我们可以点击左上角第三个图标,通过对象占内存的百分比定位异常
第一个和其他比起来,明显占比太大,可能不正常,然后,展开该行数据,定位到具体文件