首先打开MAT软件,如下:
选择打开一个Dump快照文件,如下:
勾选上图红框部分,表示要进行内存泄漏的分析。
出现饼状图,如下所示:
接着MAT还会列出几个可能存在内存泄漏的问题,拿第一个问题来分析,如下:
这个问题已经表示的很清晰了,main线程通过局部变量引用的对象占用了32.04%左右的内存空间,然后这些对象是一个java.lang.Object[]数组。
先点击Details看下详细信息,如下:
以从上到下的顺序看下来,可以发现是main线程中引用了一个ArrayList对象,ArrayList对象里面是一个java.lang.Object[]数组,数组中的每一个元素是UserInfo对象。
那现在可以确定了是UserInfo对象创建过多,占据了大量内存空间,那么到底是哪段代码中创建了这么多的UserInfo对象,不可能整个系统的去找,这时候需要追踪线程执行代码的堆栈信息,点击See stacktrace即可查看到线程执行代码堆栈的调用链,如下:
这样就定位到了具体的类以及具体的执行代码行数,那么就可以在系统里找到该类,并分析该类的代码了,该类代码如下:
import com.example.springboot.codedemo.UserInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class MAT试用代码 {
public static void main(String[] args) throws InterruptedException {
List<UserInfo> userInfos = new ArrayList<>();
for (int i = 0; i < 10000; i++) {
UserInfo userInfo = new UserInfo();
userInfos.add(userInfo);
}
TimeUnit.MINUTES.sleep(60);
}
}
可以发现代码的逻辑确实有问题,新建了大概10000个UserInfo对象,同时还睡眠了60分钟,导致方法无法结束,引用没有失效,那么这10000个对象自然就一直占用着内存空间了。