2025年hprof文件怎么分析 mat(hprof文件怎么分析)

hprof文件怎么分析 mat(hprof文件怎么分析)nbsp nbsp nbsp nbsp MAT 工具是基于 Eclipse 平台开发的 本身是一个 Java 程序 是一款很好的内存分析工具 所以如果堆快照比较大的话 则需要一台内存比较大的分析机器 并给 MAT 本身加大初始内存 这个可以修改安装目录中的 MemoryAnalyz ini 文件 nbsp amp

大家好,我是讯享网,很高兴认识大家。



       MAT 工具是基于 Eclipse 平台开发的, 本身是一个 Java 程序, 是一款很好的内存分析工具, 所以如果堆快照比较大的话, 则需要一台内存比较大的分析机器, 并给 MAT 本身加大初始内存, 这个可以修改安装目录中的 MemoryAnalyzer.ini 文件。

jemalloc内存分析工具_jemalloc内存分析工具
讯享网

     在MAT中,我们一般比较常用的几个小工具,如下图标识所示

jemalloc内存分析工具_垃圾回收_02

 

jemalloc内存分析工具_内存泄漏_03

    柱状图中,主要看每个class对应的实例数、浅堆、深堆等。如下图所示

jemalloc内存分析工具_jemalloc内存分析工具_04

     从这个图的展示效果看出,和“jmap -histo <pid> ”命令展示的效果很像。

     而我们大部分情况下,我们关注重点,是深堆或浅堆的incoming和outgoing两项,那么这两项指的是什么呢?

1、对象的引入(incoming references)

     通俗的来讲,就是哪些对象把当前对象引用了,那么那些对象对于当前对象来说就是一些引入对象。

2、对象的引出(outgoing references)

     通俗的来讲,就是当前对象中引用了哪些对象,那么那些对象对于当前对象来说就是一些引出对象。

     下面就使用例子进行说明,准备如下代码

    那么这一段码的意图,可以翻译为下面的图所示

jemalloc内存分析工具_jvm_05

       下面我们就来分析对象C的Incoming和outgoing

        将代码使用main方法运行起来,然后使用MAT连接。

        注意MAT不单单只打开 dump 日志,也可以打开正在运行的 JVM 进程, 跟 arthas 有点类似,效果是一样的,只是一个是动态的,一个是日志导出那个时刻的。

        使用MAT连接正在运行的进程方式如下图所示

jemalloc内存分析工具_内存泄漏_06

       选中如图中标识的这个进程并双出打开

jemalloc内存分析工具_垃圾回收_07

jemalloc内存分析工具_jvm_08

jemalloc内存分析工具_垃圾回收_09

jemalloc内存分析工具_垃圾回收_10

jemalloc内存分析工具_java_11

jemalloc内存分析工具_jvm_12

        这个 outgoing references 和 incoming references 非常有用, 因为我们做 MAT 分析一般时对代码不了解, 排查内存泄漏也好, 排查问题也好, 垃圾回收中有一个很重要的概念, 可达性分析算法, 那么根据这个引入和引出, 我就可以知道这些对象的引用关系, 在 MAT 中我们就可以知道比如 A,B,C,D,E,F 之间的引用关系图, 便于做具体问题的分析。

1、概念

        浅堆(shallow heap) 代表了对象本身的内存占用, 包括对象自身的内存占用, 以及“为了引用” 其他对象所占用的内存。

        深堆(Retained heap) 是一个统计结果, 会循环计算引用的具体对象所占用的内存。 但是深堆和“对象大小” 有一点不同, 深堆指的是一个对象被垃圾回收后, 能够释放的内存大小, 这些被释放的对象集合, 叫做保留集(Retained Set)

2、浅堆大小的计算

        我们知道,一个对象的大小是由三个部分组成,即对象头、实例数据、对齐填充。

        而我们在实际使用中,一个对象会引用其它的对象或一些基本的成员变量。那么这个浅堆大小的计算公式如下

        其中,各成员变量大小之和就是实例数据,如果存在继承的情况,需要包括父类成员的变量。

        除了对象,我们还需要知道数组类型对象的浅堆该如计算。计算体公式如下

        这里的类型变量大小*数组长度, 就是实例数据, 强调是变量不是对象本身

3、实例辨析

        下面,给出一张图,我们来看一下,A、B、D这三个对象的深堆和浅堆是怎么得出来的

jemalloc内存分析工具_内存泄漏_13

        1、对于A对象而言,浅堆就是自身的大小,即大小为10;深堆的计算可就没有这么简单了,前面说过,对象的深堆是指如果对象被回收了,它所能释放出多少空间,那这么这个释放出来的空间就是深堆大小。从图中,可以看出从A出发,是有6个对象实例,而每个实例的大小是10,但是对象本身的大小是10,所以A的深堆就是70

        2、对于B对象而言,按照A对象的计算方式,不能算出,它的浅堆大小是10,而深堆大小是30

        3、对于D对象而言,如果D被回收了,它也只释放出的空间大小为10,即它自身的大小。所以它的浅堆和深堆都是10。因此,如果我们在使用MAT工具在分析时,看到浅堆和深堆的大小是一样的话,就可以断定,这个对象就没有引用其它对象了。

       下面再看一个图

jemalloc内存分析工具_jemalloc内存分析工具_14

        在这种情况下, 对象A的深堆大小将从之前的 70 减小到 40 个字节。如果对象A被垃圾回收了, 则将仅会影响C、 F 和 G 对象的引用,所以仅对象C、F和G 将被垃圾回收。另一方面, 由于H持有对B的引用,对象B、D和E将继续存在于内存中。即使 A 被垃圾回收,B、D和E也不会从内存中删除。 

        总结:我们可以看到在进行内存分析时,浅堆和深堆是两个非常重要的概念,尤其是深堆,影响着回收这个对象能够带来的垃圾回收的效果,所以在内存分析中,我们往往会去找那些深堆比较的大的对象, 尤其是那些浅堆比较小但深堆比较大的对象, 这些对象极有可能是问题对象。

内存泄露检测

       在日常开发中,我们可能会遇到内存泄露问题而不自知,这种问题将会是致命的,如果不找出其中的根原,那么这么始终是一个定时炸弹。那么对于内存泄露这一类的问题,就可以使用MAT工具进行分析。

       下面,准备一段简单的代码,如下

       我们将这段代码使用main方法运行起来,并使用MAT进行连接

jemalloc内存分析工具_java_15

jemalloc内存分析工具_jvm_16

jemalloc内存分析工具_jemalloc内存分析工具_17

        从上图中,可以看到,存在一个”hl-thread”的线程,它的深堆和浅堆的差距非常的巨大。持有99.53%的对象,数据被一个HashMap所持有。

        那么这个就是一个泄露点,因为在代码中对线程做了标识 。所以我们在日常的开发中,如果有用到线程的,最好还是给线程取上名称,这样对排查问题有很大的帮助。

        所以, 如果是对于特别明显的内存泄漏, 在这里能够帮助我们迅速定位, 但通常内存泄漏问题会比较隐蔽, 我们需要做更加复杂的分析。

支配树视图

jemalloc内存分析工具_java_18

jemalloc内存分析工具_jemalloc内存分析工具_19

        从上图的层层分解得出。原来是“hl-thread”的深堆和浅堆比例很多(深堆比浅堆多很多,一般经验都是找那些浅堆比较小,同时深堆比较大的对象)

        经过分析,内存泄露点就在于此。

线程视图

       想要看具体的引用关系, 可以通过线程视图。 线程在运行中是可以作为 GC Roots 的。 我们可以通过线程视图展示了线程内对象的引用关系, 以及方法调用关系, 相对比 jstack 获取的栈 dump, 我们能够更加清晰地看到内存中具体的数据。

jemalloc内存分析工具_jemalloc内存分析工具_20

       还有另外一段是陷入无限循环,这个是相互引用导致的(进行问题排查不用被这种情况给误导了,这样的情况一般不会有问题,可达性分析算法的解决了相互引用的问题) 。

jemalloc内存分析工具_垃圾回收_21

柱状图视图

       柱状图视图,可以看到除了对象的大小, 还有类的实例个数。 结合 MAT 提供的不同显示方式, 往往能够直接定位问题。 也可以通过正则过滤一些信息,我们在这里输入MAT,过滤猜测的、可能出现问题的类, 可以看到, 创建的这些自定义对象, 刚好100个对象实例,而在代码中指定就是100

jemalloc内存分析工具_jemalloc内存分析工具_22

jemalloc内存分析工具_内存泄漏_23

        下面我们看一下对象A的引入,即A被哪些对象引用了。

jemalloc内存分析工具_java_24

 

jemalloc内存分析工具_java_25

Path To GC Roots

jemalloc内存分析工具_jvm_26

jemalloc内存分析工具_java_27

       使用这种方式, 即可在引用之间进行跳转, 方便的找到所需要的信息(这里从对象反推到了线程 hl-thread) ,也可以快速定位到有内存泄漏的问题代码。

高级功能QOL

        MAT工具支持一种类似于 SQL 的查询语言 OQL(Object Query Language) ,这个查询语言VisualVM工具也支持,不过一般情况下不用VisualVM工具。使用方法如下图

        查询A对象

jemalloc内存分析工具_java_28

jemalloc内存分析工具_垃圾回收_29

      当然了,QOL用还有更多的用法,可以参考网址 http://tech.novosoft-us.com/products/oql_book.htm

小讯
上一篇 2025-05-27 14:17
下一篇 2025-06-06 16:44

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/199811.html