JVM 内存分析工具 Memory Analyzer Tool(MAT)的深度讲解

目录

一. 前言

二. MAT 使用场景及主要解决问题

三. MAT 基础概念

3.1. Heap Dump

3.2. Shallow Heap

3.3. Retained Set

3.4. Retained Heap

3.5. Dominator Tree

3.6. OQL

3.7. references

四. MAT 功能概述

4.1. 内存分布

4.2. 对象间依赖

4.3. 对象状态

4.4. 按条件检索对象

4.5. 常见内存分析工具对比

五. Quick Start 及使用技巧

5.1. Quick Start

5.2. 使用技巧及注意事项


一. 前言

    Memory Analyzer Tool(简称:MAT),是一款快速便捷且功能强大丰富的 JVM 堆内存离线分析工具。其通过展现 JVM 异常时所记录的运行时堆转储快照(Heap Dump)状态(正常运行时也可以做堆转储分析),帮助定位内存泄漏问题或优化大内存消耗逻辑。

二. MAT 使用场景及主要解决问题

场景一:内存溢出,JVM 堆区或方法区放不下存活及待申请的对象。如:高峰期系统出现 OOM(Out of Memory)异常,需定位内存瓶颈点来指导优化。

场景二:内存泄漏,不会再使用的对象无法被垃圾回收器回收。如:系统运行一段时间后出现 Full GC,甚至周期性 OOM 后需人工重启解决。

场景三:内存占用高。如:系统频繁 GC ,需定位影响服务实时性、稳定性、吞吐能力的原因。

三. MAT 基础概念

3.1. Heap Dump

    Heap Dump 是 Java 进程堆内存在一个时间点的快照,支持 HPROF 及 DTFJ 格式,前者由 Oracle 系列 JVM 生成,后者是 IBM 系列 JVM 生成。其内容主要包含以下几类:
1. 所有对象的实例信息:对象所属类名、基础类型和引用类型的属性等。
2. 所有类信息:类加载器、类名、继承关系、静态属性等。
3. GC Root:GC Root 代表通过可达性分析来判定 JVM 对象是否存活的起始集合。JVM 采用追踪式垃圾回收(Tracing GC)模式,从所有 GC Roots 出发通过引用关系可以关联的对象就是存活的(且不可回收),其余的不可达的对象(Unreachable object:如果无法从 GC Root 找到一条引用路径能到达某对象,则该对象为Unreachable object)可以回收。
4. 线程栈及局部变量:快照生成时刻的所有线程的线程栈帧,以及每个线程栈的局部变量。

3.2. Shallow Heap

    Shallow Heap 代表一个对象结构自身所占用的内存大小,不包括其属性引用对象所占的内存。如 java.util.ArrayList 对象的 Shallow Heap 包含8字节的对象头、8字节的对象数组属性 elementData 引用 、 4字节的 size 属性、4字节的 modCount 属性(从 AbstractList 继承及对象头占用内存大小),有的对象可能需要加对齐填充但 ArrayList 自身已对齐不需补充,注意不包含 elementData 具体数据占用的内存大小。

3.3. Retained Set

    一个对象的 Retained Set,指的是该对象被 GC 回收后,所有能被回收的对象集合(如下图所示,G 的 Retain Set 只有 G 并不包含 H,原因是虽然 H 也被 G 引用,但由于 H 也被 F 引用 ,G 被垃圾回收时无法释放 H);另外,当该对象无法被 GC 回收,则其 Retained set 也必然无法被 GC 回收。

3.4. Retained Heap

    Retained Heap 是一个对象被 GC 回收后,可释放的内存大小,等于释放对象的 Retained Heap 中所有对象的 Shallow Heap 的和(如下图所示,E 的 Retain Heap 就是 G 与 E 的 Shallow Heap 总和,同理不包含 H)。

3.5. Dominator Tree

    如果所有指向对象 Y 的路径都经过对象 X,则 X 支配(dominate) Y(如下图中,C、D 均支配 F,但 G 并不支配 H)。Dominator tree 是根据对象引用及支配关系生成的整体树状图,支配树清晰描述了对象间的依赖关系,下图左的 Dominator tree 如下图右下方支配树示意图所示。支配关系还有如下关系:
1. Dominator tree 中任一节点的子树就是被该节点支配的节点集合,也就是其 Retain Set。
2. 如果 X 直接支配 Y,则 X 的所有支配节点均支配 Y。

3.6. OQL

    OQL 是类似于 SQL 的 MAT 专用统一查询语言,可以根据复杂的查询条件对 dump 文件中的类或者对象等数据进行查询筛选。

3.7. references

    outgoing references、incoming references 可以直击对象间依赖关系,MAT 也提供了链式快速操作。
1. outgoing references:对象引用的外部对象(注意不包含对象的基本类型属性。基本属性内容可在 inspector 查看)。
2. incoming references:直接引用了当前对象的对象,每个对象的 incoming references 可能有 0 到多个。

四. MAT 功能概述

    MAT 的产品能力非常丰富,工作原理是对 dump 文件建立多种索引,并基于索引来实现:1. 内存分布;2. 对象间依赖(如实体对象引用关系、线程引用关系、ClassLoader引用关系等);3. 对象状态(内存占用量、字段属性值等);4. 条件检索(OQL、正则匹配查询等)。这四大核心功能,并通过可视化展现辅助 Developer 精细化了解 JVM 堆内存全貌。

4.1. 内存分布

全局概览信息:堆内存大小、对象个数、类的个数、类加载器的个数、GC root 个数、线程概况等全局统计信息。

Dominator tree:按对象的 Retain Heap 排序,也支持按多个维度聚类统计,最常用的功能之一。

Histogram:罗列每个类实例的内存占比,包括自身内存占用量(Shallow Heap)及支配对象的内存占用量(Retain Heap),支持按 package、class loader、super class、class 聚类统计,最常用的功能之一。

Leak Suspects:直击引用链条上占用内存较多的可疑对象,可解决一些基础问题,但复杂的问题往往帮助有限。

Top Consumers:展现哪些类、哪些 class loader、哪些 package 占用最高比例的内存。

4.2. 对象间依赖

References:提供对象的外部引用关系、被引用关系。通过任一对象的直接引用及间接引用详情(主要是属性值及内存占用),进而提供完善的依赖链路详情。

Dominator tree:支持按对象的 Retain Heap 排序,并提供详细的支配关系,结合 references 可以实现大对象快速关联分析。

Thread overview:展现转储 dump 文件时线程栈帧等详细状态,也提供各线程的 Retain Heap 等关联内存信息。

Path To GC Roots:提供任一对象到 GC Root 的链路详情,帮助了解不能被 GC 回收的原因。

4.3. 对象状态

最核心的是通过 inspector 面板提供对象的属性信息、类继承关系信息等数据,协助分析内存占用高与业务逻辑的关系。

集合状态的检测,如:通过 ArrayList 或数组的填充率定位空集合空数组造成的内存浪费、通过 HashMap 冲突率判定 hash 策略是否合理等。

4.4. 按条件检索对象

OQL:提供一种类似于SQL的对象(类)级别统一结构化查询语言。如:查找 size=0 且未使用过的 ArrayList: select * from java.util.ArrayList where size=0 and modCount=0;查找所有的String的 length 属性的: select s.length from instanceof String s。

内存分布及对象间依赖的众多功能,均支持按字符串检索、按正则检索等操作。

按虚拟内存地址寻址,根据对象的十六进制地址查找对象。

此外,为了便于记忆与回顾,整理了如下脑图:

4.5. 常见内存分析工具对比

下图中 Y 表示支持,N 表示不支持,时间截至发稿前。

产品功能MATJProfilerVisual VMjhatjmaphprof
对象关联分析、深浅堆、GC ROOT、内存泄漏检测、线程分析、提供自定义程序扩展扩展YNNNNN
离线全局分析YNYYNN
内存实时分配情况NYYYYY
OQLYNYNNN
内存分配堆栈、热点比例NYNNNN
堆外内存分析NNNNNN

注 1:Dump 文件包含快照被转储时刻的 Java 对象在堆内存中的分布情况,但快照只是瞬间的记录,所以不包含对象在何时、在哪个方法中被分配这类信息。

注 2:一般堆外内存溢出排查可结合 gperftools 与 btrace 排查,本文不展开介绍。

五. Quick Start 及使用技巧

5.1. Quick Start

1. 安装 MAT:【下载链接】;也可直接集成到 Eclipse IDE中(路径:Eclipse → Help → Eclipse Marketplace → 搜 “MAT”)。

2. 调节 MAT 堆内存大小:MAT 分析时也作为 Java 进程运行,如果有足够的内存,建议至少分配 dump 文件大小 * 1.2 倍的内存给 MAT,这样分析速度会比较快。方式是修改 MemoryAnalyer.ini文件,调整 Xmx 参数(Windows 可用搜索神器 everything 软件查找并修改、MAC OS 一般在 /Applications/mat.app/Contents/Eclipse/MemoryAnalyzer.ini,如找不到可用 Alfred 软件查询修改)。

3. 获取堆快照 dump 文件(堆转储需要先执行 Full GC,线上服务使用时请注意影响),一般用三种方式:
1>. 使用 JDK 提供的 jmap 工具,命令是 jmap -dump:format=b,file=文件名 进程号。当进程接近僵死时,可以添加 -F 参数强制转储:jmap -F -dump:format=b,file=文件名 进程号。
2>. 本地运行的 Java 进程,直接在 MAT 使用 File → accquire heap dump 功能获取。
3>. 启动 Java 进程时配置JVM参数:-XX:-HeapDumpOnOutOfMemoryError,当发生 OOM 时无需人工干预会自动生成 dump文件。指定目录用 -XX:HeapDumpPath=文件路径来设置。

4. 分析 dump 文件:路径是 File → Open Heap Dump ,然后 MAT 会建立索引并分析,dump 文件较大时耗时会很长。分析后 dump 文件所在目录会有后缀为 index 的索引文件,也会有包含 HTML 格式的后缀为 zip 的文件。

5. 完成索引计算后,MAT 呈现概要视图(Overview),包含三个部分:
1>. 全局概览信息,堆内存大小、类数量、实例数量、Class Loader数量。
2>. Unreachable Object Histogram,展现转储快照时可被回收的对象信息(一般不需要关注,除非 GC 频繁影响实时性的场景分析才用到)。
3>. Biggest Objects by Retained Size,展现经过统计过的哪几个实例所关联的对象占内存总和较高,以及具体占用的内存大小,一般相关代码比较简单情况下,往往可以直接分析具体的引用关系异常,如内存泄漏等。此外也包含了最大对象和链接支持继续深入分析。

6. 如果代码比较复杂,需要继续使用 MAT 各种工具并结合业务代码进一步分析内存异常的原因。最常用的几项如下: 
1>. 查看堆整体情况的:Histogram、Dominator tree、Thread details等(各功能入口整理如下)

2>. MAT 分析过的 Top Consumers 、Leak Suspects 等

5.2. 使用技巧及注意事项

1. 注意对运行进程的性能影响:Heap Dump 时会先进行 Full GC,另外为保证对象数据视图一致,需要在安全点 Stop The World 暂停响应,线上服务进行务必注意性能影响。可以采取以下技巧减少影响:
1>. 先禁用入口流量,再执行 dump 动作。
2>. 选择影响较小时 dump 内存。
3>. 使用脚本捕获指定事件时 dump 内存。

2. Dump 文件及建立的索引文件可能较大,如果开发机配置不足无法分析,可在服务器先执行分析后,基于分析后的索引文件直接查看结果,另外也需要注意磁盘占用问题:
1>. 大文件分析方法:一般 dump 文件不高于分析机主存 1.2 倍可直接在开发机分析;若 dump 文件过大,可以使用 MAT 提供的脚本在配置高的高配机器先建立索引再直接展现索引分析结果(一般是 Linux 机器,可以使用 MAT 提供的脚本:./ParseHeapDump.sh $HEAPDUMP,堆信息有 unreachable 标记的垃圾对象,在 dump 时也保存了下来,默认不分析此部分数据,如需要在启动脚本 ParseHeapDump.sh 中加入:-keep_unreachable_objects)。
2>. 如果不关注堆中不可达对象,使用“live”参数可以减小文件大小,命令是 jmap -dump:live,format=b,file=
3>. Dump 前主动手动执行一次 FULL GC ,去除无效对象进一步减少 dump 堆转储及建立索引的时间。
4>. Dump文件巨大,建立索引后发现主视图中对象占用内存均较小,这是因为绝大部分对象未被 GC Roots 引用可释放。
5>. Dump 时注意指定到空间较大的磁盘位置,避免打满分区影响服务。
6>. 建立 dump 索引机器的磁盘空间需要足够大,一般至少是 dump 文件的两倍,因为生成的中间索引文件也较大,如下图:

3. 其他

1>. JDK 版本问题:如遇“VMVersionMismatchException”,使用启动目标进程的 JDK 版本即可。
2>. 部分核心功能主界面未展现,问题足够复杂时需打开,如 MAT 默认不打开 inspector,如需根据对象数据值做业务分析,建议打开该视图。
3>. 配置了 HeapDumpOnOutOfMemoryError 参数,但 OutOfMemoryError 时但没有自动生成 dump 文件,可能原因有三个:
    3.1>. 应用程序自行创建并抛出 OutOfMemoryError;
    3.2>. 进程的其他资源(如线程)已用尽;
    3.3>. C 代码(如 JVM 源码)中堆耗尽,这种可能由于不同的原因而出现,例如在交换空间不足的情况下,进程限制用尽或仅地址空间的限制,此时 dump 文件分析并无实质性帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/216167.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

飞天使-linux操作的一些技巧与知识点3-http的工作原理

文章目录 http工作原理nginx的正向代理和反向代理的区别一个小技巧dig 命令巧用 http工作原理 http1.0 协议 使用的是短连接,建立一次tcp连接,发起一次http的请求,结束,tcp断开 http1.1 协议使用的是长连接,建立一次tc…

IntelliJ IDEA 自带HTTP Client接口插件上传文件示例

如何使用IntelliJ IDEA自带的HTTP Client接口插件进行文件上传的示例。在这个示例中,我们将关注Controller代码、HTTP请求文件(xxx.http),以及文件的上传和处理。 Controller代码 首先,让我们看一下处理文件上传的Co…

建筑学VR虚拟仿真情景实训教学

首先,建筑学VR虚拟仿真情景实训教学为建筑学专业的学生提供了一个身临其境的学习环境。通过使用VR仿真技术,学生可以在虚拟环境中观察和理解建筑结构、材料、设计以及施工等方面的知识。这种教学方法不仅能帮助学生更直观地理解复杂的建筑理论&#xff0…

【Database】什么是数据库?常见的数据库类型有哪些?

什么是数据库?常见的数据库类型有哪些? 首先,什么是数据库?把它想象成一个数字游乐场,我们以结构化的方式组织和存储大量信息。现在,让我们来谈谈数据库的主要类型。 关系型数据库: 想象一下…

【Linux】cat 命令使用

cat 命令 cat(英文全拼:concatenate)命令用于连接文件并打印到标准输出设备上。 可以使用cat连接多个文件、创建新文件、将内容附加到现有文件、查看文件内容以及重定向终端或文件中的输出。 cat可用于在不同选项的帮助下格式化文件的输出…

ARP欺骗攻击

一.大概原理 ARP:address solution protocol 地址解析协议 ARP是一种基于局域网的TCP/IP协议,arp欺骗就是基于此协议的漏洞来达成我们的目的的,局域网中的数据传输并不是用ip地址传输的,而是靠mac地址。 我们如果出于某种目的想…

Feign-基于Feign远程调用

目录 一、Feign、RestTemplate对比 二、Feign使用步骤 2.1. 引入依赖 2.2. 在service的启动类添加注解,开启Fergn的功能 2.3. 编写Feign客户端 一、Feign、RestTemplate对比 利用RestTemplate发起远程调用的代码: String url "http://userservice/user/&quo…

【flutter对抗】blutter使用+ACTF习题

最新的能很好反编译flutter程序的项目 1、安装 git clone https://github.com/worawit/blutter --depth1​ 然后我直接将对应的两个压缩包下载下来(通过浏览器手动下载) 不再通过python的代码来下载,之前一直卡在这个地方。 如果读者可以…

gin投票系统3

对应视频v1版本 1.优化登陆接口 将同步改为异步 原login前端代码&#xff1a; <!doctype html> <html lang"en"> <head><meta charset"utf-8"><title>香香编程-投票项目</title> </head> <body> <m…

【计算机二级MS Office】word(上)

word&#xff08;上&#xff09; 文件选项卡保存和另存为属性检查文档 开始选项卡字体更改字体和字号设置中文和英文为两种不同字体的快捷方式介绍其余图标文本效果突出颜色如何挑选字体颜色字符底纹带圈字符字体对话框&#xff08;隐藏&#xff09; 段落五种对齐方式&#xff…

Python 自动化之处理docx文件(一)

批量筛选docx文档中关键词 文章目录 批量筛选docx文档中关键词前言一、做成什么样子二、基本架构三、前期输入模块1.引入库2.路径输入3.关键词输入 三、数据处理模块1.基本架构2.如果是docx文档2.1.读取当前文档内容2.2.遍历匹配关键字2.3.触发匹配并记录日志 3.如果目录下还有…

Python从入门到精通八:Python文件操作

文件的编码 思考&#xff1a;计算机只能识别&#xff1a;0和1&#xff0c;那么我们丰富的文本文件是如何被计算机识别&#xff0c;并存储在硬盘中呢&#xff1f; 答案&#xff1a;使用编码技术&#xff08;密码本&#xff09;将内容翻译成0和1存入。 编码技术即&#xff1a;…

代码随想录刷题题Day11

刷题的第十一天&#xff0c;希望自己能够不断坚持下去&#xff0c;迎来蜕变。&#x1f600;&#x1f600;&#x1f600; 刷题语言&#xff1a;C / Python Day11 任务 ● 理论基础 ● 递归遍历 ● 迭代遍历 ● 统一迭代 1 二叉树理论基础 1.1 二叉树的种类 &#xff08;1&…

LNMP网站架构分布式搭建部署

1. 数据库的编译安装 1. 安装软件包 2. 安装所需要环境依赖包 3. 解压缩到软件解压缩目录&#xff0c;使用cmake进行编译安装以及模块选项配置&#xff08;预计等待20分钟左右&#xff09;&#xff0c;再编译及安装 4. 创建mysql用户 5. 修改mysql配置文件&#xff0c;删除…

计网 - LVS 是如何直接基于 IP 层进行负载平衡调度

文章目录 模型LVS的工作机制初探LVS的负载均衡机制初探 模型 大致来说&#xff0c;可以这么理解&#xff08;只是帮助我们理解&#xff0c;实际上肯定会有点出入&#xff09;&#xff0c;对于我们的 PC 机来说&#xff0c;物理层可以看成网卡&#xff0c;数据链路层可以看成网卡…

图论-并查集

并查集(Union-find Sets)是一种非常精巧而实用的数据结构,它主要用于处理一些不相交集合的合并问题.一些常见的用途有求连通子图,求最小生成树Kruskal算法和最近公共祖先(LCA)等. 并查集的基本操作主要有: .1.初始化 2.查询find 3.合并union 一般我们都会采用路径压缩 这样…

【Spark精讲】Spark任务运行流程

Spark任务执行流程 部署模式是根据Drvier和Executor的运行位置的不同划分的。client模式提交任务与Driver进程在同一个节点上&#xff0c;而cluster模式提交任务与Driver进程不在同一个节点。 Client模式 Clinet模式是在spark-submit提交任务的节点上运行Driver进程。 …

Vue3-14- 【v-for】循环数组-解构的操作

说明 v-for 在遍历数组的时候&#xff0c;可以使用解构的语法&#xff0c;直接将数组中对象元素的属性解构出来&#xff0c; 从而实现直接使用对象属性值的效果。语法格式 &#xff1a; v-for"({属性名1,属性名2},索引变量名) in 数组名"具体的使用请看代码&#xf…

Conda 搭建简单的机器学习 Python 环境

文章目录 Conda 概述Conda 常用命令Conda 自身管理查看 Conda 版本更新 Conda清理索引缓存添加镜像源设置搜索时显示通道地址查看镜像源删除镜像源 环境管理创建虚拟环境删除虚拟环境查看所有虚拟环境复制虚拟环境激活虚拟环境关闭虚拟环境导入、导出环境 包管理虚拟环境下安装…

数据可视化:解析跨行业普及之道

数据可视化作为一种强大的工具&#xff0c;在众多行业中得到了广泛的应用&#xff0c;其价值和优势不断被发掘和利用。今天就让我以这些年来可视化设计的经验&#xff0c;讨论一下数据可视化在各个行业中备受青睐的原因吧。 无论是商业、科学、医疗保健、金融还是教育领域&…