小案例
程序
import java.util.ArrayList; import java.util.List; public class Main { public static void main(String[] args) throws Exception { List<Dandan> list = new ArrayList<>(); while (true) { list.add(new Dandan()); } } } class Dandan {}
获取dump文件
-Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\Users\25682\Desktop\aaa
其中Xmx是设置堆的最大值,HeapDumpOnOutOfMemoryError 设置当出现OOM的时候生成dump文件,HeapDumpPath表示生成的dump文件的位置
在上面的程序中添加这几个参数就会在指定的路径下获取到一个dump文件
分析dump文件
MAT分析工具的获取
https://blog.csdn.net/weixin_39621669/article/details/110668789
注意:我下载的是1.10.0版本,下载高版本的话可能需要你装更高版本的JDK
分析dump文件
内存占用过大的对象是什么
把dump文件导入到MAT中,如下图所示
点击finish后进入主页面,如下图所示,可以发现main线程是有问题的
点击图中菜单的按钮,根据数量排序,找到数量最大的对象,我们发现Dandan对象是可疑的。
这个对象被谁引用
点击下图中菜单栏中的按钮,我们会选择之前怀疑的main线程,选中并且点击
发现main线程和Dandan对象确实是有联系的,因此可以推断出 发生OOM的对象是被main线程关联的
定位到具体的代码
点击下图中的按钮,然后就出现了下图中类似线程调用栈的过程,从下往上看,并且后面有执行的代码行数,就可以定位到具体的代码