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

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

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

一、安装和装设置

1.1 mac安装

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

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

安装遇到的坑

  1. 启动直接报错,系统默认的workspace是只读的,更换掉即可。怎么更换呢,在文件/Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini中进行修改。
  1. 启动后,UI界面没反应,参考:https://www.eclipse.org/forums/index.php/t/1090889/,换个包即可。这个问题我遇到过很多次。

1.2 mat的设置

配置mat的堆内存大小

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

配置MAT的使用

MAT的配置页面可以从Window——>Preferences找到,如下图所示。

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格式的。

二、基本概念

Heap Dump

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

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

  • 对象信息:类名、属性、基础类型和引用类型
  • 类信息:类加载器、类名称、超类、静态属性
  • gc roots:JVM中的一个定义,进行垃圾收集时,要遍历可达对象的起点节点的集合
  • 线程栈和局部变量:快照生成时候的线程调用栈,和每个栈上的局部变量

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

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。

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. 支配树中的边跟对象引用图中的引用关系并不是一一对应的。

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文件

  1. 通过MAT生成dump文件 通过这个路径找到生成dump文件的对话框

选择一个进程,点击finish即可

  1. 通过jmap命令生成dump文件
  • 命令格式:jmap -dump:live,format=b,file=heap.bin <pid>
  • 注意:如果要保留heapdump中的不可达对象,则需要把”:live“去掉,即使用命令”jmap -dump,format=b,file=heap.bin <pid>“
  1. 通过设置JVM参数自动生成 使用-XX:+HeapDumpOnOutOfMemoryError这个JVM参数,在Java进程运行过程中发生OOM的时候就会生成一个heapdump文件,并写入到指定目录,一般用-XX:HeapDumpPath=${HOME}/logs/test来设置。

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

mat分析dump分析_MAT从入门到精通(一)相关推荐

  1. mat分析dump分析_使用Eclipse Memory Analyzer Tool(MAT)分析线上故障(一)

    来源:  https://sourl.cn/ggYpYX 前言 Eclipse Memory Analyzer Tool(MAT)是一个强大的基于Eclipse的内存分析工具,可以帮助我们找到内存泄露 ...

  2. python3入门到精通 pdf_解析《Python3标准库》PDF中英文代码+《算法之美指导工作与生活的算法》PDF中英文+《Scratch编程从入门到精通PDF》趣学...

    我想Python之所以流行,原因在于:1. 语言本身优美,表达力强.适合做快速原型开发.且学习曲线平坦,上手快. 2. Python标准库正是应对了这第二点.丰富的库实现得以让python程序员迅速完 ...

  3. envi 文件 生成mat_JVM 内存分析工具 MAT 的深度讲解与实践——入门篇

    1. MAT 工具简介 MAT(全名:Memory Analyzer Tool),是一款快速便捷且功能强大丰富的 JVM 堆内存离线分析工具.其通过展现 JVM 异常时所记录的运行时堆转储快照(Hea ...

  4. 使用MAT(Memory Analyzer Tool)工具分析dump文件--转

    原文地址:http://gao-xianglong.iteye.com/blog/2173140?utm_source=tuicool&utm_medium=referral 前言 生产环境中 ...

  5. eclipse mat 分析dump文件,打开文件报错,out of memeory

    eclipse mat 分析dump文件,打开文件报错,out of memeory 解决: 1.打开eclipse报out of memeory通用 window-->Preferences- ...

  6. linux使用MAT分析dump文件

    unzip MemoryAnalyzer-1.8.0.20180604-linux.gtk.x86_64.zip 修改MAT的内存大小, 注意这个大小要根据你dump文件大小来的,如果dump文件是5 ...

  7. MAT分析dump文件显示大小比jmap查询结果小

    背景 有朋友向我吐槽,她在一台测试机器上调试,使用jmap查看堆内存占用时,发现年轻代+老年代占用的内存,和dump下堆转储文件使用MAT分析显示的内存不一样,百思不得其解.重现现象如下: jmap显 ...

  8. linux分析mat使用教程,使用MAT(Memory Analyzer Tool)工具分析dump文件

    <使用MAT(Memory Analyzer Tool)工具分析dump文件> 前言 生产环境中,尤其是吃大内存的JVM,一旦出现内存泄露等问题是非常容易引发OutofMemory的,如果 ...

  9. oracle dump 源码,AIX 下的 core dump 分析入门

    AIX 下的 core dump 分析入门 (), 工程师, IBM 作者毕业于中国科学技术大学,目前任职于 IBM,主要方向为 AIX 平台移植.性能优化.问题定位等. 简介: 本文简要介绍了 AI ...

最新文章

  1. Python正则表达式初识(十)附正则表达式总结
  2. 2021-02-25 matlab 字符串和数字同时写入excel
  3. 九妹带你了解oracle
  4. 数据切分——Atlas介绍
  5. LeetCode 第 19 场双周赛(231 / 1120,前20.6%)
  6. 云原生人物志 | Pulsar翟佳:社区的信任最重要
  7. Anaconda 国内镜像源整理
  8. 【转】在 2016 年做 PHP 开发是一种什么样的体验?(一)
  9. windows server 查看当前登陆的用户 query user
  10. Qt connect parent widget 连接父控件的信号槽
  11. codeforces 27 E. Number With The Given Amount Of Divisors(数论+dfs)
  12. Linux 操作系统常用以下哪种编译器,Linux 操作系统期末复习资料(Alpha版)
  13. 朋友圈宣传文案 朋友圈产品推广文案模板怎么写?
  14. 今年晋升本没抱希望,已有绩效更好的同事将参加晋升,leader却临时让我也去答辩,怀疑自己被拉去陪跑,该怎么办?...
  15. 解线性方程组的各种情况
  16. 传输层协议(TPC和UDP介绍)
  17. hadoop配置文件workers
  18. 极光推送demo下载运行错误
  19. 双链表(double_linked_list):(增、删、改、查、逆置)的C++的例子,稍微改一下,就成C。
  20. linux服务器上装r,linux服务器安装R语言及Rstudio server

热门文章

  1. Mysql,Zookeeper,Redis,Mongodb压力测试结果
  2. 3.2. @RestController
  3. iOS - OC SQLite 数据库存储
  4. BCM_I2C函数更改
  5. LNMP实现服务器轮询负载均衡
  6. 彭文华:详解数字化转型的破局之道(附直播视频)
  7. 这又何止呢的openeim002
  8. 既然开发了 飞鸽传书 就一定要帮助人
  9. 韩媒体:900万人个人信息被非法泄露到中国
  10. C++ UNICODE 编程从入门到精通