# Memory Analyzer (MAT) 在实际开发中的使用

Memory Analyzer (MAT) 在实际开发中的使用

概述

  • MAT,全称Memory Analysis Tools,是一款分析Java堆内存的工具,可以快速定位到堆内泄漏问题。该工具提供了两种使用方式,一种是插件版,可以安装到Eclipse使用,另一种是独立版,可以直接解压使用。

官网地址:Eclipse Memory Analyzer Open Source Project | The Eclipse Foundation

注意点

在这里插入图片描述

  • 如果堆文件实际大小很大比如8G,但是用Mat打开后内存信息只有1G,那么可以通过下面的设置显示无法访问对象的详细信息,需要删除之前导入进来的重新导入
    在这里插入图片描述

基本使用

检查概述

  • 通过文件> 打开堆转储…打开堆转储…查看概述页。 如果您有可用的堆转储,请立即尝试打开堆转储。
    在这里插入图片描述

在右侧,您可以找到转储的大小和 类、对象和类装入器。
如果转储的总大小远小于 文件是可能的 堆转储包含许多垃圾 对象 在下一个垃圾桶时丢弃 收集。显示无法访问对象的步骤见注意点中描述的方法。

获取直方图

  • 从工具栏中 直方图图标选择直方图图标以列出每个类的实例数, 浅尺寸(ShallowHeap)和保留尺寸(Retained Heap

在这里插入图片描述

  • 浅堆是一个对象所消耗的内存,X的保留堆是X的保留集合中所有对象的浅大小之和,即X保留的存活内存。

    在这里插入图片描述

View the Dominator Tree

  • 支配树显示堆转储中最大的对象。树的下一层列出了那些对象,如果对父节点的所有传入引用被删除,这些对象将被垃圾收集。支配树是一种强大的工具,用于研究哪些对象使哪些其他对象保持存活。同样,树可以按照类加载器(例如组件)和包分组,以简化分析。

在这里插入图片描述

到GC根的路径

  • 从对象到GC根的(反向)引用链——所谓的GC根路径——解释了为什么对象不能被垃圾收集。该路径有助于解决Java中的经典内存泄漏:这些泄漏的存在是因为即使程序逻辑不再访问对象,对象仍然被引用。

在这里插入图片描述

使用示例

制作堆dump

HeapDumpOnOutOfMemoryError
  • 其实在很多时候我们是不知道何时会发生OOM,所以需要在发生OOM时自动生成dump文件。其实很简单,只需要在启动时加上如下参数即可。HeapDumpPath表示生成dump文件保存的目录。
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\tmp
  • 当系统堆溢出的时候会自动生成快照文件,项目上一般都会配置这个参数
  • 内存溢出Idea 显示如下:
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to java_pid25396.hprof ...
Heap dump file created [1486916275 bytes in 5.168 secs]
Jmap 生成堆Dump
  • 首先要查找运行的Java程序的pid,然后使用jmap命令生成dump文件。file后面是保存的文件名称,1246则是java程序的PID
jmap -dump:format=b,file=user.dump 1246

Mat打开堆快照

  • 模拟堆栈溢出,如下图所示,从图中可以看出大对象占用 800M左右,RetainedSIze占用637.4M

在这里插入图片描述

Histogram

  • 列举类的实例信息,从这里面明显的可以看到,这个对象没有GCRoot而且占用比较大,很有可能是内存泄露的地方

在这里插入图片描述

Thread Overview

  • 线程分析概览,展示出了所有的线程,主线程,以及各个线程中的浅堆和深堆占用的大小,类加载器,是否守护线程等信息

在这里插入图片描述

执行内存泄露报告

  • 点击Leak Suspects 查看存在内存泄露的地方
    在这里插入图片描述

列出大对象

  • 从下面的这个图可以判断出程序中存在死循环

在这里插入图片描述

查看对象占用树

  • 在此视图中列出了每个对象(Object Instance)与其引用关系的树状结构,同时包含了占用内存的大小和百分比。通过Dominator Tree视图可以很容易的找出占用内存最多的几个对象(根据Retained HeapPercentage排序);

在这里插入图片描述

元素介绍

GcRoots

GC Root(Garbage Collection Root)是指在Java虚拟机中被直接或间接引用的对象集合,它们被认为是存活对象,不能被垃圾回收器回收。GC Root的作用是为垃圾回收器提供一个初始的扫描位置,以便确定哪些对象是可达的,哪些对象是不可达的。垃圾回收器会从GC Root开始扫描,并标记所有可达对象,最终将不可达对象回收掉。

GC Root包括以下几种类型:

  • 虚拟机栈中引用的对象

  • 方法区中类静态属性引用的对象

  • 方法区中常量引用的对象

  • Native方法中引用的对象

  • 活动线程中的对象

  • 当前类加载器加载的类的对象

  • 例如下面的图中GCRoots没有到达 object5、object6、object7,因此他们三标记为可以被回收

在这里插入图片描述

Shallow Heap

  • Shallow Heap 为对象自身占用的内存大小,不包括它引用的对象。

Retained set

  • 对象本身和他持有引用的对象和这些对象的retained set所占内存大小的总和
    在这里插入图片描述

在这里插入图片描述

with incoming references

在这里插入图片描述

  • 对象 A 和对象 B 持有对象 C 的引用
  • 对象 C 持有对象 D 和对象 E 的引用
  • 对象 CIncoming References:拥有对象 C 的引用的所有对象都称为 Incoming references。在此示例中,对象 CIncoming references是对象 A、对象 BC 的类对象

with outgoing references

  • 对象 COutgoing References:对象 C 引用的所有对象都称为 Outgoing References。在上面图中,对象 Coutgoing references是对象 D、对象 E

参考文献

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值