Eclipse MAT 内存分析工具

Exlipse MAT 是一款强大的 Java 堆内存分析工具,我们可以通过该工具实现对 Java 堆内存的分析。
官网。实现查找内存泄漏以及查看内存消耗的情况。

MAT 使用

首先去官网下载对应的软件压缩包,下载地址。MAT 提供了多种平台的软件包支持,包括 Windows , Mac OSX ,Linux 等,可以根据你当前的系统进行下载。由于我使用的是 Win10,因此下载了 Windows(x86_64)版本的。
在这里插入图片描述
需要注意的是新版的 MAT 需要系统的 Java 版本在 11 及以上,如果你的版本不够,则需要重新配置一下环境中的 Java 版本。
在这里插入图片描述
对于老版的 MAT,是作为一个 Eclipse IDE 插件提供的,新版的 MAT 增加了独立的 MAT 支持,使得用户不需要额外安装 Eclipse 也可以使用 MAT。

初识 MAT

在分析堆快照之前,首先需要导出应用程序的堆快照。我们可以使用 jmapjconsoleJava Visual VM实现堆快照的导出。除此之外使用 MAT 也能够实现堆快照的导出。
单击左上角的File菜单下的Accquire Heap Dump 选项,选择对应正在运行的 Java 进程即可。
在这里插入图片描述

解析 dump 出的堆内存快照

除了直接在 MAT 中获取正在运行的应用程序的堆快照之外,也可以通过 “Open Heap Dump” 来打开一个本地的堆快照。

建议将堆内存快照文件单独放在一个文件夹下,因为 MAT 在分析堆内存快照的时候会在对应目录下生成一些索引文件,因此将堆内存快照单独放在一个文件夹下便于查看。

在这里插入图片描述
在打开堆快照后,会出现如下的界面:
在这里插入图片描述
可以根据界面的指引选择你想用的功能即可。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

浅堆(Shallow heap)和深堆(Retained Heap)

在 MAT 中会发现有两列分别描述了对象的浅堆(Shallow heap) 和深堆(Retained Heap)。这两列都是用于描述对象的大小,以 java.lang.String为例:
在这里插入图片描述
可以发现这里 java.lang.String 的浅堆大小都是 24 字节,而深堆大小与具体对象有关,各不相同。

  • 浅堆(Shallow Heap) 用于描述一个对象结构所占用的内存大小
  • 深堆(Retained Heap) 用于描述一个对象被 GC 后,可以释放的真实内存的大小。
浅堆(Shallow Heap)

浅堆是指一个对象所消耗的内存。
浅堆的大小只与对象的结构有关,与对象的实际内容无关,也就是说在一个 Java 进程块中,相同类型的所有对象,浅堆的大小是固定不变的。

在这里插入图片描述

在32 位操作系统 和 64 位操作系统上,一个对象所占用的内存大小也各不相同,但基本数据类型所占用的内存大小是不变的,如下:

基本数据类型所占内存大小(字节)
byte1
short2
int4
long8
float4
double8
char2
boolean1

有区别的是引用类型,主要是和 CPU 的字长有关。

  • 在 32 位操作系统上,一个对象引用占 4 个字节(4x8=32)
  • 在 64 为操作系统上,一个对象引用占 8 个字节(8x8=64)

引用类型实际上就是一个地址指针。在 32 位操作系统上,占用 4字节(4x8=32),在 64位操作系统上,占用 8 字节(8x8=64)。

在 JDK1.6 之后,默认开启了指针压缩(-XX:UseCompressedOops),则64位操作系统上地址指针占用 4字节。

而对于对象,对象头在不同的操作系统上大小也不同。

  • 在 32 位操作系统上,一个对象头大小占 8 个字节(4字节 Markword + 4字节 类型指针)
  • 在 64 位操作系统上,一个对象头大小占 16 个字节(8字节 MarkWord + 8字节 类型指针)

在 64 为操作系统上,如果开启了指针压缩,则对象头的大小为 12 字节(8字节 MarkWord + 4 字节类型指针)

在这里插入图片描述
现在我们来尝试分析一下 java.lang.String 类型的对象的浅堆为什么是 24 字节吧。
由于开启了指针压缩,

  • 首先 java.lang.String 的对象头为 12 字节,
  • 包含一个 名为 hash 类型为 int 的属性,占 4 字节;
  • 包含一个 名为 value 类型为 引用类型(ref) 的属性,占 4 字节;
  • 在64 位操作系统中,为了和 8 字节对齐,会增加 4 字节的对齐填充

总共占用为(12 + 4 + 4 + 4) = 24 字节。
在这里插入图片描述

深堆(Retianed Heap)

而深堆的计算就稍微有些复杂了,我们不仅需要计算该对象的大小,而且还需要计算该对象所包含的引用对象的大小才能够真正计算出该对象深堆的大小。

首先需要列出一个对象以及对象中所包含的引用:
在这里插入图片描述

使用 List objects 可以列出该类型的全部对象,其中with outgoing references 表示列出该对象所包含的对象,with incoming reference表示列出其他包含该对象的对象。
有点绕口,这里举个例子:
在这里插入图片描述

对于 String(“zhangsan”) 来说,
User 对象包含了该 String,处于 “zhangsan” 的上游,那么该 User 对象是 “zhangsan” 的 incoming。
而 “zhangsan” 所包含的 char[8] 处于 “zhangsan” 的下游 ,则是 “zhangsan” 的 outgoing。

如果要计算深堆的话,我们需要将 String 对象的下游列出来,因此要选择 with outgoing reference

在这里插入图片描述
我们这里计算需要将该对象的浅堆加上该对象所包含引用对象的深堆相加。
比如这里 88 字节 = 24(Shallow Heap) + 64(char[24])

支配树视图(dominator tree)

在这里插入图片描述
支配树视图可以体现对象实例间的支配关系。

注意:对象支配树中,某一个对象的子树,表示在该对象被回收后,也将被回收的对象的集合。

打印出的堆内存快照过大怎么办

可以使用 MAT 的命令行模式首先进行对内存的预分析.
在这里插入图片描述
打开命令行,执行如下命令:

ParseHeapDump.bat <path/to/heap_dump> org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components
# 示例
ParseHeapDump.bat D:\Downloads\heap_dump\java.hprof org.eclipse.mat.api:suspects org.eclipse.mat.api:overview org.eclipse.mat.api:top_components
参数说明
org.eclipse.mat.api:suspects生成内存泄漏检查报告
org.eclipse.mat.api:overview生成内存分析报告
org.eclipse.mat.api:top_components生成大对象内存占用报告

在命令执行完成后,对应目录下,就会出现相对应的报告的压缩包:
在这里插入图片描述
我们可以直接解压后,通过浏览器浏览该报告,也可以使用 MAT 读取报告。
在这里插入图片描述
在这里插入图片描述

参考资料

Eclipse MAT内存分析
Eclipse MAT内存分析工具
jvm内存快照dump文件太大,怎么分析
JVM heap dump分析

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MAT工具使用说明.docx MAT(Memory Analyzer Tool)工具入门 一MAT简介 MAT(Memory Analyzer Tool),一个基于Eclipse内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。 二 使用MAT意义 当服务器应用占用了过多内存的时候,会遇到OutOfMemoryError。如何快速定位问题呢?Eclipse MAT的出现使这个问题变得非常简单。它能够离线分析dump的文件数据。 四 MAT操作流程 1先调用jdk的工具得到heap使用情况 我安装的是jdk1.6 C:/>java -version java version "1.6.0_11" Java(TM) SE Runtime Environment (build 1.6.0_11-b03) Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing) 2调用jdk工具jps查看当前的java进程 C:/>jps 3504 Jps 3676 Bootstrap 3496 org.eclipse.equinox.launcher_1.0.201.R35x_v20090715.jar 3调用jmap工具得到信息 C:/>jmap -dump:format=b,file=heap.bin 3676 Dumping heap to C:/heap.bin ... Heap dump file created 这时,我们的C盘根目录,就生成了heap.bin文件。 4用eclipse的file---->open打开这个文件,首先是一个启动图: 这里可以选择查看 (1)内存泄露报表,自动检查可能存在内存泄露的对象,通过报表展示存活的对象以及为什么他们没有被垃圾收集; (2)对象报表,对可颖对象的分析,如字符串是否定义重了,空的collection、finalizer以及弱引用等。 我这里选择的是查看内存报表,以下是截的简略图: 通过报表展示,蛮清楚的,下面还有详细的说明,这里就没有帖图了,有兴趣的可以继续探究。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值