趣文网 > 作文大全

java内存溢出问题分析过程二(附MAT超全操作文档)

2020-11-20 16:05:01
相关推荐

前言

java程序的性能问题定位,一直都是开发者需要面对的一个“拦路虎”, 在前面的两篇文章中,已经介绍了Heap dump的概念和生成方式,以及Shallow heap和Retained heap以及GC ROOT的概念,本篇文章,我们继续来介绍一些新的概念和基于一个dump案例,详尽的介绍,该程序OOM后,改如何去定位具体原因。

再次提及dominator tree(支配树)

如果你玩过竞技类游戏,肯定会很熟悉Dominating -主宰比赛这个单词。

在Memory Analyzer工具中提供了对象图的支配树。将对象引用图转换为dominator tree可以让轻松地确定Retained heap最大内存块和对象之间保持活动的依赖关系,相当于主宰了整个JVM的感觉。

我们把java对象之间的引用关系看做一张有向图,如果所有指向Y的对象路径都要经过X,则我们说X支配Y。如果X是离对象Y最近的支配对象,则我们说对象X是Y的直接支配者( immediate dominator)。

再强化记忆一下,X对象要直接支配Y,必须满足这两点:

指向Y的对象路径都要经过X。X对象是离Y最近的支配对象。

左边是对象的引用图,右边是支配树。

C节点的子树就是所有被C支配的节点的集合,也称为C的Retained Set。

由图可以看出,C是E的直接支配节点,所以C的上级支配节点B也可以支配E。

dump分析初步

首先用MemoryAnalyzer工具打开dump文件。

从整体情况可以看出,1.6 gb的堆内存,有的对象占了1.1g。

怀疑是有内存泄漏,我们通过Leak Suspect Report报告查看

内存泄漏分析报告显示有两项问题:

一是WebappClassLoader 类加载器装载的A.A[][] 对象占了约1.2g(70.40%)。二是一个名为TP-Processor9的线程持有本地变量多达337M(占了19.58%)。通过分析报告,我们初步可以推断出OOM的问题应该出在这两个地方,我们逐个击破。

内存泄漏点一

先来看类装载器加载的AA对象。我们点开内存泄漏报告的Detail,查看其详情。

Shortest Paths To the Accumulation Point视图可以看出正是和org.apache.catalina.loader.WebappClassLoader这个GC root相连导致当前Retained Heap占用相当大的对象无法被回收,而对象数量居然达到了170288个。

Accumulated Objects in Dominator Tree视图,可以看出AA对象中,到底是什么内嵌对象占用heap高。

可以看出,170288个AA对象数组内部,主要是AH对象 和 AM对象。

我们继续向下看,通过按class类分组,来看看具体占用比例情况。

按class分组后,冒出了一个Af对象,反倒AH占用不是那么多了。

小结:AH/AM/Af三个对象占用堆内存很高,并且它们的gc root是WebappClassLoader。

内存泄漏点二

TP-Processor9 线程本身就是GC root,故只有一条数据。

以这个线程为GC ROOT来看看,它的支配树是什么样的?

可以看到19.58%的Retained Heap就是来源于TP-Processor9 线程本身。这意味着,如果这个线程能被gc回收掉,则至少能释放19.58%的堆内存。

以TP-Processor9 线程为gc root的支配树,按class分类,可以发现Am对象本身占用163m左右。

Detail明细的最后由于当前怀疑泄露点为TP-Processor9 线程对象,故展示了线程明细信息,调用栈信息。

小结:TP-Processor9 线程内部可能导致内存泄漏。

整合两个泄漏点结论

从两个泄漏点,得出的结论,我们可以将问题定位到如下元素上: TP-Processor9 线程、170288个AA对象数组、AM、AH对象。

我们来看看AA对象数组的(Outgoing Reference)引用其他外部对象的情况

可以看到com.fr.report.core.A.A[170288][] @ 0xcfdb62a0 这个对象引用外部对象的情况,一共是170289个 com.fr.report.core.A.A[25] 对象。

并且其Shallow Heap 和Retained Heap大小一样。 170289 * 120 = 20434680。 约占20M内存。

所以这个对象应用的外部对象,不是根因。

接下来,再分析Incomming Reference(被其他外部对象引用的情况)。

可以看到com.fr.report.core.A.A[170288][] @ 0xcfdb62a0

这个包含170288个元素的对象,主要被 com.fr.report.worksheet.PageRWorkSheet @ 0xcfd02188 对象持有。

出现了一系列的ReportPage和ClippedECPage对象。

从依赖树和对象地址可以知道,ClippedECPage引用ReportPage对象。

所以只需要重点关注ClippedECPage对象。继续分析ClippedECPage对象的依赖树如下:

其他的 Shallow Heap占用都不高,唯独一个对象数组,占用较大,并且它的Retained Heap很大。

问题应该就出在ClippedECPage类上,进一步分析它存储的 com.fr.page.ReportPage。 这个对象是: 用于展示及打印的页面 执行完一个多Sheet的Report后, 会生成多个ReportPage。 分析它的属性:

连续查看了两个对象,发现其中的属性,currentPageNumber为591和592。

总页数为599. 可以推断出,是在做分页操作。

可以看到当时浏览器的信息

操作的文件:xxx/customized/xxx表.xxx

结论

结合ReportPage类的作用: 用于展示及打印的页面 执行完一个多Sheet的Report后, 会生成多个ReportPage。

最后结论为:

在执行查询时间段为: 2018/6/8 15:57:15 - 2018/6/8 16:0:53时 一次性打印599页数据,导致OOM,程序宕机崩溃。

至此,就完成了一个Dump文件的分析,我准备了一个mat的操作手册,比较全面。

在微信侠梦的开发笔记中回复mat,即可领取,希望能帮助到你。

阅读剩余内容
网友评论
相关内容
延伸阅读
小编推荐

大家都在看

坚持作文开头 记事的作文500字以上 关于长辈的作文 谜语作文 畅想十年后的自己作文 属予作文以记之的作 集体的温暖作文 四年级游览顺序作文 爱国抒情作文 成功的要素作文 关于漫画的作文400字 用游览顺序写一篇作文 割稻谷的作文 关于和谐的作文素材 我的老师作文250字 溺水的作文500字 白云山风景作文 宝塔山作文 假如我是孙悟空作文500字 慢下来会更精彩作文 写四川的作文 北京印象作文 优秀高中作文 以励志为主题的作文 我的梦想大学生作文 包粽子500字作文 九年级英语各单元作文范文 下雨蚂蚁搬家作文 没有付出就没有收获英语作文 我心目中的好老师作文600字