当前位置 : 首页 » 文章分类 :  开发  »  Eclipse-MAT

Eclipse-MAT

Eclipse MAT 使用笔记

MAT(Memory Analyzer Tool) 是 Eclipse 提供的一个 JVM 内存分析工具。


M1 Mac 安装 Eclipse MAT 1.13.0

从 MAT 1.13.0 Release 版本开始已原生支持 M1 芯片,从官网 https://www.eclipse.org/mat/downloads.php 下载 Mac OSX (Mac/Cocoa/AArch64) 版本。

安装注意事项:

1、MAT 最低需要 Java 11 版本,需安装 arm64 版 jdk 11,否则安装报错。
先将系统默认 jdk 版本改为 11,等安装 MAT 完成后将系统默认 jdk 再改为 8 也不影响 mat 运行。

2、安装报错:
java.lang.IllegalStateException: The platform metadata area could not be written: /Volumes/mat/mat.app/Contents/MacOS/workspace/.metadata. By default the platform writes its content under the current working directory when the platform is launched. Use the -data parameter to specify a different content area for the platform.

解决:
应用程序 -> mat -> 右键 -> 显示包内容 -> Contents -> Eclipse -> 修改 MemoryAnalyzer.ini 添加 -data 参数指定数据目录,其中 /private/tmp/mat 是自己新建的文件夹

-data
/private/tmp/mat

由于现在还没安装成功,在 “应用程序” 中找不到 mat,将双击打开 dmg 后看到的 mat 直接拖到 “应用程序” 中即可,注意不能直接在这里的 mat 上右键修改包内容,这里是只读的。

修改后完整的 MemoryAnalyzer.ini 内容如下:

-startup
../Eclipse/plugins/org.eclipse.equinox.launcher_1.6.400.v20210924-0641.jar
-data
/private/tmp/mat
--launcher.library
../Eclipse/plugins/org.eclipse.equinox.launcher.cocoa.macosx_1.2.400.v20211117-0650
-vmargs
-Xmx1024m
-Dorg.eclipse.swt.internal.carbon.smallFonts
-XstartOnFirstThread

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

  • 浅堆(Shallow Heap) 表示对象结构本身所占内存的大小,不包含引用的对象,单位 bytes。
  • 深堆(Retained Heap) 表示这个对象以及 仅被 它所直接或间接引用的对象所占的内存之和,单位 bytes,表示一个对象被GC回收后可以真实释放的内存大小。

浅堆(Shallow Heap)是指一个对象结构本身所消耗的内存。一个对象引用会占据4或8个字节(依赖操作系统架构),一个int类型会占据4个字节,long型变量会占据8个字节,每个对象头需要占用8个字节。
浅堆的大小只与对象的结构有关,与对象的实际内容无关。根据堆快照格式不同,对象的大小可能会向8字节进行对齐。
比如 Java 6 中 String 对象有以下成员:value:char[], hash:int, count:int, offset:int,3个int值共占12字节,对象引用占用4字节,对象头8字节,合计24字节。

对象A的 保留集(Retained Set) 指当对象A被垃圾回收后,可以被释放的所有的对象集合(包括对象A本身),即对象A的保留集可以被认为是 只能通过对象A 被直接或间接访问到的所有对象的集合。通俗地说,就是指 仅被对象A 所持有的对象的集合。深堆是指对象的保留集中所有的对象的浅堆大小之和。
一个对象的深堆指只能通过该对象访问到的(直接或间接)所有对象的浅堆之和,即对象被回收后,可以释放的真实空间。

平常说的对象的实际大小,可以用一个对象所能触及的所有对象(包括自己)的浅堆大小之和来计算,这个值一般是大于深堆大小的,因为所触及的对象可能同时被好多对象引用。


浅堆深堆举例
对象A引用了C和D,对象B引用了C和E,则: 对象A的浅堆只有自己,深堆包括A自己和D,因为C同时也在B的引用链中所以不包含在A的深堆中,A的实际大小包括ACD三个对象。 对象B的浅堆只有自己,深堆包括B自己和E,因为C同时也在A的引用链中所以不包含在B的深堆中,B的实际大小包括BCE三个对象。

Memory Analyzer > Concepts > Shallow vs. Retained Heap
https://help.eclipse.org/latest/topic/org.eclipse.mat.ui.help/concepts/shallowretainedheap.html?cp=55_2_2

Eclipse MAT 安装及使用
https://www.cnblogs.com/loong-hon/p/10475143.html


Histogram 直方图

查看引用的对象(Outgoing References)

查看当前对象引用的对象,即出引用(Outgoing References)
右键 -> List objects -> with outgoing references

查看对象被谁引用(Incomming References)

查看当前对象被谁引用,即 入引用(Incomming References)
右键 -> List objects -> with incoming references


Dominator Tree 支配树

Memory Analyzer > Concepts > Dominator Tree
https://help.eclipse.org/latest/topic/org.eclipse.mat.ui.help/concepts/dominatortree.html?cp=55_2_3

Class Name 图标左下角带红点的是可以被 GC Roots 访问到的,即当前不能被回收的。

查对象到GC Root的路径

查看对象是否被其他 GC Root 引用?
对象上点右键 -> Path to GC Roots -> exclude weak references
排除弱引用是因为弱引用是不会阻止对象被垃圾回收的,所以不会成为内存泄漏的对象。

经常用于分析某个大对象为什么没被回收

查看对象的保留集

对象上点右键 -> Show Retained Set -> Finish


查看线程和局部变量

点击工具栏的小齿轮图标,打开 thread_overview 页面,可以查看线程堆栈、局部变量。
带有 <local> 标记的,就为当前帧栈的局部变量


上一篇 Arthas

下一篇 Java-Math

阅读
评论
1.3k
阅读预计5分钟
创建日期 2022-05-18
修改日期 2022-07-01
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论