java 内存溢出问题分析过程
C 节点的子树就是所有被 C 支配的节点的集合,也称为 C 的 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》开源 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 类分组,来看看 Java 开源项目【ali1024.coding.net/public/P7/Java/git】 具体占用比例情况。
按 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)引用其他外部对象的情况
最后
文章中涉及到的知识点我都已经整理成了资料,录制了视频供大家下载学习,诚意满满,希望可以帮助在这个行业发展的朋友,在论坛博客等地方少花些时间找资料,把有限的时间,真正花在学习上,所以我把这些资料,分享出来。相信对于已经工作和遇到技术瓶颈的朋友们,在这份资料中一定都有你需要的内容。
评论