JVM监控-Arthas、Mat

参考

arthas官方文档
如何读懂火焰图?
idea-插件 快捷生成命令
MAT工具

1、arthas使用场景

  • 这个类从哪个 jar 包加载的? sc/sm
  • 我改的代码为什么没有执行到?jad
  • 如何跟踪某个方法的返回值、入参… ? watch
  • 查看cpu占用高的线程/死锁 thread
  • 时空隧道-记录下指定方法每次调用的入参和返回信息 tt (TimeTumple)

2、mat使用场景

分析内存。使用相关工具将内存dump出来

2.1、histogram 直方图

在这里插入图片描述
MAT的直方图和jmap的-histo子命令一样,都能够展示各个类的实例数目以及这些实例的Shallowheap总和和Retained heap

2.1.1with outgoing references

在这里插入图片描述

此对象引用了哪些对象

2.1.2、with incoming references

在这里插入图片描述
此对象被谁引用

2.1.3 深堆retained heap

对象A的保留集指当对象A被垃圾回收后,可以被释放的所有的对象集合(包括对象A本身),即对象A的保留集可以被认为是只能通过对象A被直接或间接访问到的所有对象的集合

2.1.3 浅堆shallow heap

浅堆(Shallow Heap)是指一个对象本身所消耗的内存

2.1.4 对象的实际大小

2.2、thread overview

在这里插入图片描述

查看系统中的Java线程、查看局部变量的信息,获得对象的引用关系

2.3、Dominator Tree(对象树)

在这里插入图片描述

左图表示对象引用图,右图表示左图所对应的支配树。对象A和B由根对象直接支配,由于在到对象C的路径中,可以经过A,也可以经过B,因此对象C的直接支配者也是根对象。对象F与对象D相互引用,因为到对象F的所有路径必然经过对象D,因此,对象D是对象F的直接支配者。而到对象D的所有路径中,必然经过对象C,即使是从对象F到对象D的引用,从根节点出发,也是经过对象C的,所以,对象D的直接支配者为对象C。

支配树的概念源自图论。MAT提供了一个称为支配树(Dominator Tree)的对象图。支配树体现了对象实例间的支配关系。在对象引用图中,所有指向对象B的路径都经过对象A,则认为对象A支配对象B

2.4 OQL

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

功能总结

  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 占用最高比例的内存

  2. 对象间依赖
    References:提供对象的外部引用关系、被引用关系。通过任一对象的直接引用及间接引用详情(主要是属性值及内存占用),进而提供完善的依赖链路详情。
    Dominator tree:支持按对象的 Retain Heap 排序,并提供详细的支配关系,结合 references 可以实现大对象快速关联分析;
    Thread overview:展现转储 dump 文件时线程栈帧等详细状态,也提供各线程的 Retain Heap 等关联内存信息。
    Path To GC Roots:提供任一对象到GC Root的链路详情,帮助了解不能被 GC 回收的原因。

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

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

  1. 按条件检索对象
    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。
    内存分布及对象间依赖的众多功能,均支持按字符串检索、按正则检索等操作。
    按虚拟内存地址寻址,根据对象的十六进制地址查找对象。

生成dump文件几种方式

使用 JDK 提供的 jmap 工具,命令是 jmap -dump:format=b,file=文件名 进程号。当进程接近僵死时,可以添加 -F 参数强制转储:jmap -F -dump:format=b,file=文件名 进程号。
本地运行的 Java 进程,直接在 MAT 使用 File → accquire heap dump 功能获取。
启动 Java 进程时配置JVM参数:-XX:-HeapDumpOnOutOfMemoryError,当发生 OOM 时无需人工干预会自动生成 dump文件。指定目录用 -XX:HeapDumpPath=文件路径 来设置

使用技巧及注意事项

1、注意对运行进程的性能影响:Heap dump 时会先进行 Full GC,另外为保证对象数据视图一致,需要在安全点 Stop The World 暂停响应,线上服务进行务必注意性能影响。可以采取以下技巧减少影响:

先禁用入口流量,再执行 dump 动作。
选择影响较小时 dump 内存。
使用脚本捕获指定事件时 dump 内存。

2、Dump 文件及建立的索引文件可能较大,如果开发机配置不足无法分析,可在服务器先执行分析后,基于分析后的索引文件直接查看结果,另外也需要注意磁盘占用问题:

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

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

常见内存工具对比

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值