MAT 入门到精通(一)

栏目: Java · 发布时间: 6年前

内容简介:尽管JVM提供了自动内存管理的机制,试图降低程序员的开发门槛,确实也实现了这一目标,在日常开发中,我们一般都不需要关心对象的内存释放。JVM大部分都是使用trace算法来判断一个对象是否该被回收,那么JVM只能回收那些从gc roots不可达的对象。

MAT 入门到精通(一)

MAT 入门到精通(一)

尽管JVM提供了自动内存管理的机制,试图降低 程序员 的开发门槛,确实也实现了这一目标,在日常开发中,我们一般都不需要关心对象的内存释放。JVM大部分都是使用trace算法来判断一个对象是否该被回收,那么JVM只能回收那些从gc roots不可达的对象。

如果我们在使用某些大的对象、集合对象或者一些三方包里的资源,忘记及时释放资源的话,还是会造成JVM的内存泄漏或内存浪费的问题。因此,如果想成为更高阶的 Java 开发工程师,我们需要了解常见的问题排查的办法和工具,这个系列的文章,准备介绍一个用来做JVM堆内存分析的工具——MAT(Memory Aanlysis Tool)。

MAT的官网在: https://www.eclipse.org/mat/ ,可以看下它的介绍——MAT是一款高性能、具备丰富功能的Java堆内存分析工具,可以用来排查内存泄漏和内存浪费的问题。

MAT的安装和设置

01

1.1

在Mac上安装MAT

MAT 支持两种安装方式,一种是"单机版“的,也就是说用户不必安装 Eclipse IDE 环境,MAT 作为一个独立的 Eclipse RCP 应用运行;另一种是”集成版“的,也就是说 MAT 也可以作为 Eclipse IDE 的一部分,和现有的开发平台集成。

这里我们考虑独立安装,在观望的下载页面,选择mac os版本的安装文件下载即可。

MAT 入门到精通(一)

1.2

安装中遇到的坑

  1. 启动直接报错,系统默认的workspace是只读的,更换掉即可。怎么更换呢,在文件 /Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini 中进行修改。 MAT 入门到精通(一)

  2. 启动后,UI界面没反应,参考: https://www.eclipse.org/forums/index.php/t/1090889/ ,换个包即可。这个问题我遇到过很多次。 MAT 入门到精通(一)

1.3

MAT的设置

配置mat的堆内存大小

我的电脑是8C16G的,那理论上分析10G的堆文件没问题,但是MAT默认的配置没有这么大,需要在 /Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini 文件中进行修改。如下图所示,我将我的MAT自己的运行时堆内存配置成了6G。 MAT 入门到精通(一)

配置MAT的使用

MAT的配置页面可以从Window——>Preferences找到,如下图所示。 MAT 入门到精通(一)

MAT的一般配置有几个选项

  1. Keep unreachable objects:如果勾选这个,则在分析的时候会包含dump文件中的不可达对象;

  2. Hide the getting started wizard:隐藏分析完成后的首页,控制是否要展示一个对话框,用来展示内存泄漏分析、消耗最多内存的对象排序。

  3. Hide popup query help:隐藏弹出查询帮助,除非用户通过F1或Help按钮查询帮助。

  4. Hide Welcome screen on launch:隐藏启动时候的欢迎界面

  5. Bytes Display:设置分析结果中内存大小的展示单位

可以看出,MAT不仅支持HPROF文件的分析,还支持DTFJ文件的分析。一般sun公司系列的JVM生成的dump文件都是HPROF格式的,IBM的JVM生成的dump文件时DTFJ格式的。

基本概念

02

2.1

Heap Dump

Heap Dump是Java进程在某个时刻的内存快照,不同JVM的实现的Heap Dump的文件格式可能不同,进而存储的数据也可能不同,但是一般来说。

Heap Dump中主要包含当生成快照时堆中的java对象和类的信息,主要分为如下几类:

  • 对象信息:类名、属性、基础类型和引用类型

  • 类信息:类加载器、类名称、超类、静态属性

  • gc roots:JVM中的一个定义,进行垃圾收集时,要遍历可达对象的起点节点的集合

  • 线程栈和局部变量:快照生成时候的线程调用栈,和每个栈上的局部变量

Heap Dump中没有包含对象的分配信息,因此它不能用来分析这种问题:一个对象什么时候被创建、一个对象时被谁创建的。

2.2

Shallow vs. Retained Heap

Shallow heap 是一个对象本身占用的堆内存大小。一个对象中,每个引用占用8或64位,Integer占用4字节,Long占用8字节等等。

Retained set ,对于某个对象X来说,它的Retained set指的是——如果X被垃圾收集器回收了,那么这个集合中的对象都会被回收,同理,如果X没有被垃圾收集器回收,那么这个集合中的对象都不会被回收。

Retained heap ,对象X的Retained heap指的时候它的Retained set中的所有对象的Shallow si的和,换句话说,Retained heap指的是对象X的保留内存大小,即由于它的存活导致多大的内存也没有被回收。

leading set ,对象X可能不止有一个,这些对象统一构成了leading set。如果leading set中的对象都不可达,那么这个leading set对应的retained set中的对象就会被回收。一般有以下几种情况:

  1. 某个类的所有实例对象,这个类对象就是leading object

  2. 某个类记载器加载的所有类,以及这些类的实例对象,这个类加载器对象就是leading object

  3. 一组对象,要达到其他对象的必经路径上的对象,就是leading object

在下面这张图中,A和B是gc roots中的节点(方法参数、局部变量,或者调用了wait()、notify()或synchronized()的对象)等等。可以看出,E的存在,会导致G无法被回收,因此E的Retained set是E和G;C的存在,会导致E、D、F、G、H都无法被回收,因此C的Retined set是C、E、D、F、G、H;A和B的存在,会导致C、E、D、F、G、H都无法被回收,因此A和B的Retained set是A、B、C、E、D、F、G、H。 MAT 入门到精通(一)

2.3

Dominator Tree

MAT根据堆上的对象引用关系构建了支配树(Dominator Tree),通过支配树可以很方便得识别出哪些对象占用了大量的内存,并可以看到它们之间的依赖关系。

如果在对象图中,从gc root或者x上游的一个节点开始遍历,x是y的必经节点,那么就可以说x支配了y( dominate )。

如果在对象图中,x支配的所有对象中,y的距离最近,那么就可以说x直接支配( immediate dominate )y。

支配树是基于对象的引用关系图建立的,在支配树中每个节点都是它的子节点的直接支配节点。基于支配树可以很清楚得看到对象之间的依赖关系。

现在看个例子,在下面这张图中

  1. x节点的子树就是所有被x支配的节点集合,也正式x的retained set;

  2. 如果x是y的直接支配节点,那么x的支配节点也可以支配y

  3. 支配树中的边跟对象引用图中的引用关系并不是一一对应的。

MAT 入门到精通(一)

2.4

Garbage Collection Roots

在MAT中,gc roots的概念跟研究垃圾收集算法时候的概念稍微有点不同。gc roots中的对象,是指那些可以从堆外访问到的对象的集合。如果一个对象符合下面这些场景中的一个,就可以被认为是gc roots中的节点:

  1. System Class:由bootstrap classloader加载的类,例如rt.jar,里面的类的包名都是 java.util.* 开头的。

  2. JNI Local:native代码中的局部变量,例如用户编写的JNI代码或JVM内部代码。

  3. JNI Global:native代码中的全局变量,例如用户编写的JNI代码或JVM内部代码。

  4. Thread Block:被当前活跃的线程锁引用的对象。

  5. Thread:正在存活的线程

  6. Busy Monitor:调用了wait()、notify()或synchronized关键字修饰的代码——例如 synchronized(object) synchronized 方法。

  7. Java Local:局部变量。例如函数的输入参数、正在运行的线程栈里创建的对象。

  8. Native Stack:native代码的输入或输出参数,例如用户定义的JNI代码或JVM的内部代码。在文件/网络IO方法或反射方法的参数。

  9. Finalizable:在finalize队列中等待它的finalizer对象运行的对象。

  10. Unfinalized:重载了finalize方法,但是还没有进入finalize队列中的对象。

  11. Unreachable:从任何gc roots节点都不可达的对象,在MAT中将这些对象视为root节点,如果不这么做,就不能对这些对象进行分析。

  12. Java Stack Frame:Java栈帧,用于存放局部变量。只在dump文件被解析的时候会将java stack frame视为对象。

  13. Unknown:没有root类型的对象。有些dump文件(例如IBM的Portable Heap Dump)没有root信息。

获取Dump文件

03

  1. 通过MAT生成dump文件 通过这个路径找到生成dump文件的对话框 MAT 入门到精通(一) 选择一个进程,点击finish即可 MAT 入门到精通(一)

  2. 通过jmap命令生成dump文件

  • 命令格式: jmap -dump:live,format=b,file=heap.bin <pid>

  • 注意:如果要保留heapdump中的不可达对象,则需要把”:live“去掉,即使用命令”jmap -dump,format=b,file=heap.bin <pid>

  • 通过设置JVM参数自动生成 使用 -XX:+HeapDumpOnOutOfMemoryError 这个JVM参数,在Java进程运行过程中发生OOM的时候就会生成一个heapdump文件,并写入到指定目录,一般用 -XX:HeapDumpPath=${HOME}/logs/test 来设置。

  • 本号专注于后端技术、JVM问题排查和优化、Java面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。

    MAT 入门到精通(一)


    以上所述就是小编给大家介绍的《MAT 入门到精通(一)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

    查看所有标签

    猜你喜欢:

    本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

    Alone Together

    Alone Together

    Sherry Turkle / Basic Books / 2011-1-11 / USD 28.95

    Consider Facebookit’s human contact, only easier to engage with and easier to avoid. Developing technology promises closeness. Sometimes it delivers, but much of our modern life leaves us less connect......一起来看看 《Alone Together》 这本书的介绍吧!

    随机密码生成器
    随机密码生成器

    多种字符组合密码

    SHA 加密
    SHA 加密

    SHA 加密工具

    RGB HSV 转换
    RGB HSV 转换

    RGB HSV 互转工具