1. 工具下载
mat下载地址: https://www.eclipse.org/mat/downloads.php
2. 测试用例
每10毫秒创建一个对象,放入list中,使之不被销毁。保持每秒100个左右的对象泄漏
package com.hz.leaksuspect;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @file: LeakSuspectDemo
* @version: 1.0
* @Description: 内存泄漏分析
* @Author: pp_lan
* @Date: 2021/5/10
*/
public class LeakSuspectDemo {
private static AtomicInteger count = new AtomicInteger(0);
public static void main(String[] args) throws InterruptedException {
LeakSuspectDemo demo = new LeakSuspectDemo();
List<Car> list = new ArrayList<>();
while (true) {
list.add(demo.new Car());
TimeUnit.MILLISECONDS.sleep(20);
}
}
public class Car {
public Car() {
count.getAndIncrement();
System.out.println(String.format("car对应存活数量%d", count.get()));
}
@Override
protected void finalize() throws Throwable {
super.finalize();
count.decrementAndGet();
}
}
}
3. 排查
3.1 运行demo
运行100s左右后,存在该对象1w个左右。运行MemeryAnalyzer进行分析
打开服务器内存快照参考
参考命令: jmap -dump:format=b,file=a.bin 27088
参考链接:https://blog.csdn.net/pp_lan/article/details/104673373 1.b部分
打开完成,获取到内存映射后,可以关闭停止demo程序
3.2 内存泄漏分析
3.3 查看可疑的内存占用情况
3.3.1 leak suspect
查看详情(Details)
发现很多Car对象创建了未被销毁,我们接下来需要查看对象调用的地方
查看调用地点
点击java.lang.Thread@ 0x..... 点击跳出菜单,选择java basic--> thread details, 进行定位。
3.6 Histogram
点击类名 List objects --> with outgoing refrence
点击 merge shortest path to Gc roots -- > excluded all phanton/soft/weak (排除虚/软/弱引用)
Object --> java basic--> thread details, 进行定位