我能读懂泄露报告,却读不懂女人心,一文带你实战内存溢出排查

喜迎周二

让我们在一个舒缓的 BGM 中开始今日话题 内存溢出

前情提要

很多伙伴,在碰到内存溢出,根本无从先下手,甚至重启已经成为解决问题的常态,面试追问场景,也只是熟练背诵八股文而已,那么这篇文章,带你详细从问题的发生到排查做一个讲解。

忽略如何发现的 OOM,以及与运维等角色协同,直接进入问题解决,来日方长,慢慢介绍。

主人公

  • 小李-某司技术一把手,年纪轻轻,财务自由,开小米 SU7
  • 小白手套-某司技术 家财万贯,只为体验生活,上级小李,开法拉利

问题出现

某天小李手机突然疯狂开始震动,监控系统告警,某服务疯狂 OOM,如果不快速处理,可能也会拖累到服务器本身, 小李心想,这些问题,我也一知半解的,那谁谁,小白手套,这次就你来吧,不懂可以问我。

小白手套OS:真倒霉,行吧 ,我来看。

小白手套不情愿的登录到了公司服务器,查看日志,果然,OOM 错误 吞没了屏幕

我能读懂泄露报告,却读不懂女人心,一文带你实战内存溢出排查_第1张图片

小白手套很快注意到了 Java heap space ,按照常理来讲,一般是堆内存被分配光了,可是生产环境,一般分配都是经过严谨评估的,嗯,对了,记得生产有配置如果发生 OOM 自动 Dump 堆内存的,我去找找这个文件,问题就会水落石出。

拿到堆文件

很快,小白手套找到了堆转储文件

神器 MAT

MAT(Memory Analyzer Tool)是一个用于分析Java堆内存使用情况和排查内存泄漏问题的强大工具。它是一个开源项目,由Eclipse基金会维护和支持。

MAT提供了一系列功能,可以帮助你识别和解决Java应用程序中的内存问题。它可以分析Java堆转储文件(通常是通过Java虚拟机的"-XX:+HeapDumpOnOutOfMemoryError"参数生成的)或运行时快照,并提供以下功能:

  1. 内存泄漏分析:MAT可以检测和分析内存泄漏,找出那些没有被正确释放的对象,从而导致内存占用过高的问题。
  2. 重复对象分析:MAT可以识别并分析堆内存中的重复对象,帮助你找出可能存在的冗余对象,并进行优化。
  3. 堆转储分析:MAT可以解析和分析Java堆转储文件,提供关于对象实例、类信息、引用关系和内存使用情况的详细信息。
  4. 内存使用统计:MAT提供了各种内存使用的统计信息,包括对象实例数量、内存占用大小、类加载器信息等,以帮助你了解应用程序的内存使用情况。
  5. 内存泄漏报告:MAT可以生成详细的内存泄漏报告,包括泄漏对象的路径、引用链和相关的堆转储信息,帮助你定位和解决内存泄漏问题。

下载地址:https://eclipse.dev/mat/downloads.php

小白手套熟练的将 Dump 文件下载到本地,并导入 MAT

内存泄露报告

翻译如下

OK,选择 Finish 后,就出现了一张简单的饼图

我能读懂泄露报告,却读不懂女人心,一文带你实战内存溢出排查_第2张图片

一眼可以看到,a 区域的内存占用达到 95 %,基本上可以定位到,问题是在这里开始的

我能读懂泄露报告,却读不懂女人心,一文带你实战内存溢出排查_第3张图片

Histogram

这时,我们通过第一个利器,Histogram 来通过柱状图,展示每个类的实例数

介绍一下每一列的含义

  • ClassName 类名
  • Objects 对象数
  • Shallow Heap(浅堆层) 对象实际占用堆的大小
  • Retained Heap (保留堆)可以理解为,如果这个对象被删除,可以省出多少内存

按照分析图来看,java.lang.Object[] 最大,接下来,排除掉 Object[] 的软引用,看它的强引用

可以看到 tomcat 某个线程创建了 Object[] 数组,Ref. Shallow Heap(引用的浅堆大小): 420,781,224个,并且给数组重复填充了值 HeapOverflowExample

换句话来说,就是一个线程引用了大量的数组对象,占用了极大的内存,从而导致堆溢出,所以根据属性可以定位到程序的确是有不恰当的地方

我能读懂泄露报告,却读不懂女人心,一文带你实战内存溢出排查_第4张图片

Domain Tree

Domain Tree 和 Histogram 类似,是通过对象栈的方式进行展示

结语

遇到 OOM 问题不要慌,先及时恢复应用,将案发现场做好保存,事后分析即可,由于业务复杂性,可能查询方式不像这样容易,通过泄露报告定位大对象 + 强引用的思路,不会出错。

名词解释

  • 内存溢出:指程序在申请内存时,没有足够的内存空间,导致出现 OutOfMemoryError
  • 内存泄露:指程序在申请内存后,无法释放申请的内存空间,时间一久从而出现 OutOfMemoryError

思考

  1. 如果你电脑只有 2G 内存,线上 Dump 文件有 20G,要怎么办呢?
  2. 除了 MAT 还有什么工具可以分析?

祝你好运!

你可能感兴趣的:(java-ee,后端,java,jvm)