美文网首页互联网科技程序员
JVM第二篇:基于Actuator生成HeapDump及基于MA

JVM第二篇:基于Actuator生成HeapDump及基于MA

作者: 小怪聊职场 | 来源:发表于2018-12-20 21:19 被阅读24次

一、使用Spring Boot Actuator生成HeapDump文件

参考我前面的文章Java|使用Spring Boot Actuator监控应用
访问http://localhost:1001/monitor/actuator/heapdump即可生成heapdump文件。

二、安装分析工具MAT

在Java程序运行中发生OOM的时候,我们可以使用强大的内存分析工具MAT进行问题跟踪,但由于习惯了使用idea开发,所以安装MAT独立版。
下载地址:https://eclipse.org/mat/downloads.php

MAT Welcome页面

三、生成分析报告

首先,启动前面安装配置好的 Memory Analyzer tool(MAT) , 然后选择菜单项 File- Open Heap Dump 来加载需要分析的堆转储文件。
加载完之后的分析过程如下:
1.选择Leak Suspects Report

选择Leak Suspects Report

2.点击Finish,生成“内存泄露分析报告”

内存泄露分析报告

3.从上面的图,我们查看到内存消耗的整体状况
从上面的“内存泄露分析报告”的饼图上,我们可以清晰地看到一个可疑对象消耗了2.3G的内存,占整个系统的98%以上。

4.继续往下看

内存泄露分析报告下部分

在图的下方还有对这个可疑对象的进一步描述。我们可以看到内存是由
com.lmax.disruptor.RingBuffer的实例消耗的,sun.misc.Launcher$AppClassLoader负责这个对象的加载。
到此,似乎也没找出根本原因(对于新手来说),继续往下看。

5.点击“Details »”,如下图所示

进入Details

我们发现,产生问题的代码段似乎与log4j有一定关系。

6.进一步定位,查看All Accumulated Objects by Class里面的内容,如下图

All Accumulated Objects by Class

点击消耗Heap最多的First 10 of 524,168 objects

点击First 10 of 524,168 objects

7.查看First 10 of 524,168 objects里的内容,如下图

`First 10 of 524,168 objects

看到这里,我们发现是有一个大对象list存放了大量的aaaaaaaaaaa_aaaaaa的值导致的。
我们通过aaaaaaaaaaa_aaaaaa在代码上进行搜索,最后发现,原来是下面的代码段导致了这个问题:

String aa = "aaaaaaaaaaaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_aaaaaaaaa_";
List<String> list = new  ArrayList();
while (true) {
    list.add(aa);
    log.info("aa:{}", list);
}

到此,我们非常顺利地完成了一次“Java内存泄漏的排查”。实际上有这个顺利吗?回答是也大概差不多。

PS:我在JVM第一篇:一个Java内存泄漏的排查案例文章中说过下面一段话:

2.2 找出导致频繁Full GC的原因
分析方法通常有两种:
1)把堆dump下来再用MAT等工具进行分析,但dump堆要花较长的时间,并且文件巨大,再从服务器上拖回本地导入工具,这个过程有些折腾,不到万不得已最好别这么干。
2)更轻量级的在线分析,使用“Java内存影像工具:jmap”生成堆转储快照(一般称为headdump或dump文件)。

发现使用Spring Boot Actuator可以推翻一下我上面的一点小误解。

感谢你的阅读,如果对你有帮助就点个赞吧,这样的鼓励会让我更有兴趣写《JVM第三篇:******》

相关文章

网友评论

    本文标题:JVM第二篇:基于Actuator生成HeapDump及基于MA

    本文链接:https://www.haomeiwen.com/subject/mdvuhqtx.html