一、MAT分析工具
jvisualvm同样可以进行一键堆转储后,直接打开这个dump 查看。但是,jvisualvm 的堆转储分析功能并不是很强大,只能查看类使用内存的直方图,无法有效跟踪内存使用的引用关系。可以查看引用链
二、排查思路:
使用 MAT 分析 OOM 问题,一般可以按照以下思路进行:
- 通过支配树功能或直方图功能查看消耗内存最大的类型,来分析内存泄露的大概原因;
- 查看那些消耗内存最大的类型、详细的对象明细列表,以及它们的引用链,来定位内存
泄露的具体点; - 配合查看对象属性的功能,可以脱离源码看到对象的各种属性的值和依赖关系,帮助我
们理清程序逻辑和参数; - 辅助使用查看线程栈来看 OOM 问题是否和过多线程有关,甚至可以在线程栈看到
OOM 最后一刻出现异常的线程。
一、支配树![](https://i-blog.csdnimg.cn/blog_migrate/283d92016927b41f0c35a37eefa27aee.png)
Retained Heap(深堆)代表对象本身和对象关联的对象占用的内存,Shallow Heap(浅堆)代表对象本身占用的内存
二、线程视图
三、案例
/**
*
* JVM 参数:
* -Xms500M -Xmx500M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./
*/
public class OomDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
while (true){
String s = IntStream.rangeClosed(0, 1000).mapToObj(i -> "a").collect(Collectors.joining("")) + UUID.randomUUID();
list.add(s);
}
}
}
- 类使用直方图
根据类使用大小排行,可以看出 是char[]
类型,也就能推断出 存储的是String类型数据, - 线程视图
- 支配树视图
可以看到list对象本身的 堆深只有24 但是它关联的确特别大
三、参考
极客时间相关教程《业务错误100例》相关