建议收藏 一文深度讲解JVM 内存分析工具 MAT及实践

1. 前言
熟练掌握 MAT 是 JAVA 高手的必备能力,但实践时大家往往需面对众多功能,眼花缭乱不知如何下手,小编也没有找到一篇完善的教学素材,所以整理本文帮大家系统掌握 MAT 分析工具 。
本文详细讲解 MAT 众多内存分析工具功能,这些功能组合使用异常强大,熟练使用几乎可以解决所有的堆内存离线分析的问题 。我们将功能划分为4类:内存分布详情、对象间依赖、对象状态详情、按条件检索 。每大类有多个功能点,本文会逐一讲解各功能的场景及用法 。此外,添加了原创或引用案例加强理解和掌握 。
如图所示:

建议收藏 一文深度讲解JVM 内存分析工具 MAT及实践

文章插图
 
【建议收藏 一文深度讲解JVM 内存分析工具 MAT及实践】为减少对眼花缭乱的菜单的迷茫,可以通过下图先整体熟悉下各功能使用入口,后续都会讲到 。
建议收藏 一文深度讲解JVM 内存分析工具 MAT及实践

文章插图
 
2. 内存分布详解及实战
2.1 全局信息概览
功能:展现堆内存大小、对象数量、class 数量、class loader 数量、GC Root 数量、环境变量、线程概况等全局统计信息 。
使用入口:MAT 主界面 → Heap Dump Overview 。
举例:下面是对象数量、class loader 数量、GC Root 数量,可以看出 class loader 存在异常 。
建议收藏 一文深度讲解JVM 内存分析工具 MAT及实践

文章插图
 
举例:下图是线程概况,可以查看每个线程名、线程的 Retained Heap、daemon 属性等 。
建议收藏 一文深度讲解JVM 内存分析工具 MAT及实践

文章插图
 
使用场景 全局概览呈现全局统计信息,重点查看整体是否有异常数据,所以有效信息有限,下面几种场景有一定帮助:
  • 方法区溢出时(Java 8后不使用方法区,对应堆溢出),查看 class 数量异常多,可以考虑是否为动态代理类异常载入过多或类被反复重复加载 。
  • 方法区溢出时,查看 class loader 数量过多,可以考虑是否为自定义 class loader 被异常循环使用 。
  • GC Root 过多,可以查看 GC Root 分布,理论上这种情况极少会遇到,笔者只在 JNI 使用一个存在 BUG 的库时遇到过 。
  • 线程数过多,一般是频繁创建线程但无法执行结束,从概览可以了解异常表象,具体原因可以参考本文线程分析部分内容,此处不展开 。
2.2 Dominator tree


    推荐阅读