分析和定位线上作业 OOM 问题利器-MAT

共 3212字,需浏览 7分钟

 ·

2020-07-28 23:17


点击上方蓝色字体,选择“设为星标

回复”资源“获取更多资源

64c8630cf78af9d421f2e12b8d3628c5.webp

8a4505ee8231ae127c388cb7be208084.webp

大数据技术与架构点击右侧关注,大数据开发领域最强公众号!

08dc39b01f7fa6068b51ef59bb6bbcae.webp

暴走大数据点击右侧关注,暴走大数据!b8273973d5c5dbc5e5b056d5d2774ad5.webp本文作者:学无止境 原文链接:https://www.cnblogs.com/duanxz/p/6046055.html在工作中可能会遇到内存溢出这种灾难性的问题,那么程序肯定是存在问题,找出问题至关重要,上一篇文章讲了jmap命令的使用方法,当然用jmap导出的文件我们也看不懂啊,那就交给memory analyzer(mat)这个工具,让他帮助我们来观察程序的内存分布情况吧。
MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析。下面来看看要怎么做呢,也许对你有用。官方文档:http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html
造成OutOfMemoryError原因一般有2种:1、内存泄露,对象已经死了,无法通过垃圾收集器进行自动回收,通过找出泄露的代码位置和原因,才好确定解决方案;2、内存溢出,内存中的对象都还必须存活着,这说明Java堆分配空间不足,检查堆设置大小(-Xmx与-Xms),检查代码是否存在对象生命周期太长、持有状态时间过长的情况。

jmap 命令生成堆信息

jmap -dump:live,format=b,file=E:/jmap/heap.dump pid
8e94508c6b14d310a16bbf06dcecf61c.webp这样在E盘的jmap文件夹里会有一个map.bin的堆信息文件这样在E盘的jmap文件夹里会有一个map.bin的堆信息文件

将堆信息导入到mat中分析

bd08beef4455ea3d380c32ba15ac2d43.webp

生成分析报告

mat可以为我们生成多个报告:

bfbcb1ae319c924644886f5fed23a86f.webp

下面来看看生成的这些数据对我们有什么帮助
ee758e5f7951b63dcd75b817065bf083.webp从上图可以看到它的大部分功能,在饼图上,你会发现转储的大小和数量的类,对象和类加载器。正确的下面,饼图给出了一个印象最大的对象转储。移动你的鼠标看到对象中的对象的细节检查在左边。下面的Action标签中:
  • Histogram可以列出内存中的对象,对象的个数以及大小。

  • Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。

  • Top consumers通过图形列出最大的object。

  • Leak Suspects通过MA自动分析泄漏的原因。

Histogram

05ff553bf9d815bf7c6c566bdc46cddb.webp
  • Class Name :类名称,java类名

  • Objects :类的对象的数量,这个对象被创建了多少个

  • Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用

  • Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和

一般来说,Shallow Heap堆中的对象是它的大小和保留内存大小相同的对象是堆内存的数量时,将释放对象被垃圾收集。保留设置一组主要的对象,例如一个特定类的所有对象,或所有对象的一个特定的类装入器装入的类或者只是一群任意对象,是释放的组对象如果所有对象的主要设置变得难以接近的。保留设置包括这些对象以及所有其他对象只能通过这些对象。保留大小是总堆大小中包含的所有对象的保留。摘自eclipse关于的详细讲解,建议大家查看Shallow heap & Retained heap,这是个很重要的概念。d183b2105e1f85bc459228c5de9ee047.webp这儿借助工具提供的regex正则搜索一下我们自己的类,排序后看看哪些相对是占用比较大的。d22e7d65f8206ec64339d36c19fdb593.webp左边可以看到类的详细使用,比如所属包,父类是谁,所属的类加载器,内存地址,占用大小和回收情况等c554b6623a1b412a07b6d99ac854de1f.webp这儿有个工具可以根据自己的需求分组查找,默认根据class分组,类似我们sql里的group by了~~eeb92967b803a8d15d65945550e295ee.webp这里可以看到上面3个选项,分别生成overview、leak suspects、top components数据,但是这儿生成的不是图表,如果要看图表在(Overview)中的Action标签里点击查看。这个是Overview中的 Heap Dump Overview视图,从工具栏中点开,这是一个全局的内存占用信息

6499c078ea616dcf756e2d41f5d65b14.webp

然后可以点开SystemProperties和Thread Overview进行查看,我这里就不贴了内容比较多。

Dominator Tree

90b90590b36950dcc866867443320a04.webp我们可以看到ibatis占了较多内存

Top consumers

b5b952826a28e7f7b5a283213fd26024.webp这张图展示的是占用内存比较多的对象的分布,下面是具体的一些类和占用。86e4ff23373c42b8d59d2e27cce5aff8.webp按等级分布的类使用情况,其实也就是按使用次数查看,java.lang.Class被排在第一cd1df2808d882471e57f5fe275691c9d.webp还有一张图是我们比较关心的,那就是按包名看占用,根据包我们知道哪些公共用的到jar或自己的包占用d6a9f30e8a95174a98056c4f43cdf539.webp这样就可以看到包和包中哪些类的占用比较高。

Leak Suspects

1782618c2aca111279c05d30a25b0a5e.webp从这份报告,看到该图深色区域被怀疑有内存泄漏,可以发现整个heap只有79.7M内存,深色区域就占了62%。所以,MAT通过简单的报告就说明了项目是有可疑代码的,具体点开详情来找到类,1d3731f00d386ff1fae2bf4dbaf89f35.webp点击鼠标,在List Objects-> with outgoing references下可以查看该类都引用了什么对象,由此查看是否因为其他对象导致的内存问题。下面继续查看pool的gc ROOT如下图所示的上下文菜单中选择 Path To GC Roots -> exclude weak references, 过滤掉弱引用,因为在这里弱引用不是引起问题的关键。进入查看即可,我这儿的代码没有问题,就不用贴了。840876ff552ef1f916628ef5d293b0d2.webp
The classloader/component "org.apache.catalina.loader.WebappClassLoader @ 0xa34cde8" occupies 19,052,864 (22.80%) bytes. The memory is accumulated in one instance of "java.util.HashMap$Entry[]" loaded by "".

Keywords
java.util.HashMap$Entry[]
org.apache.catalina.loader.WebappClassLoader @ 0xa34cde8
这段话是在工具中提示的,他告诉我们WebappClassLoader占了19,052,864 字节的容量,这是tomcat的类加载器,JDK自带的系统类加载器中占用比较多的是HashMap。这个其实比较正常,大家经常用map作为存储容器。除了在上一页看到的描述外,还有Shortest Paths To the Accumulation Point和Accumulated Objects部分,这里说明了从GC root到聚集点的最短路径,以及完整的reference chain。观察Accumulated Objects部分,java.util.HashMap的retained heap(size)最大,所以明显类实例都聚集在HashMap中了。66a164bee1fca0c08e614fb8096194c8.webp来看看Accumulated Objects by Class区域,这里能找到被聚集的对象实例的类名。java.util.HashMap类上头条了,被实例化了5573次,从这儿看出这个程序不存在什么问题,因为这个数字是比较正常的,但是当出问题的时候我们都会看到比较大的自定义类会在前面,而且占用是相当高。当然,mat这个工具还有很多的用法,这里把我了解的分享给大家,不管如何,最终我们需要得出系统的内存占用,然后对其进行代码或架构,服务器的优化措施!欢迎点赞+收藏+转发朋友圈素质三连


文章不错?点个【在看】吧! ?

浏览 16
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报