jmap(Java Memory Map)是jdk自带的java内存映像工具,使用jmap能够系统运行时的内存信息,同时能够将内存dump下来,分析内存泄露的问题。 这里我们使用它 -dump 选项,将内存信息dump到服务器某个地方,然后传到本地使用内存分析工具MAT进行内存分析。
jmap -dump:live,format=b,file=文件路径/文件名 pidlive:就是只dump 活着的对象 format=b 使用二进制 file= 快照文件保存路径
Java内存分析工具,它可以打开我们dump下来的内存快照,帮助我们定位内存泄露问题。 下载地址:连接 MemoryAnalyzer
这里我们演示方便,就直接造200个对象,每个对象占用1m内存,然后使用jmap 命令将该程序内存信息dump 下来,使用MAT进行定位内存泄露问题。
演示代码:
public class GCTest { public static void main(String[] args) { List<Data> list =new ArrayList<>(); for (int i=0;i<200;i++){ list.add(new Data()); } try { // 程序sleep 10分钟 TimeUnit.MINUTES.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } class Data { byte[] array1 = new byte[1024 * 1024]; //1m }使用jmap 进行dump 先是用jps 找到程序的进程号 接着进行dump:
jmap -dump:live,format=b,file=dmp.hprof 58837打开MAT,然后file—》Open Heap Dump ----》 选择你dump下来那个文件打开就可以了 Leak Suspects Report 这个选项 最好勾上,能够帮你自动分析内存泄露问题。 往下滑, 可以看到各个内存泄露嫌疑点 Problem Suspect 1,下面有个Details 点开可以看到具体什么对象: 点开Deatils,就可以看到具体的大对象,你还可以点击这些对象,在左侧能看到它的详细信息。 再回到泄露嫌疑点 也就是 Problem Suspect 1,Details上面有个See stacktrace, 这个是查看栈信息的,能够通过栈信息定位到代码的具体位置。
本文主要是讲解了 分析内存泄露的 一个思路,并没有将jmap ,MAT 涉及的知识讲详细,而是介绍了一下分析的过程,当我们线上服务 频繁Full GC 并且 每次GC回收效果不佳的时候,我们就要分析一下内存信息了,看看内存里面是否有那种 大对象,然后长时间有GC Roots 引用着,比如说从数据库一下 撸几十万条数据,然后进行长时间计算分析,这种问题就需要具体业务具体分析了。