MAT

概述

MAT(Memory Analyzer Tool)工具是一款功能强大的Java堆内存分析器, 可以用于查找内存泄漏以及查看内存消耗情况

MAT是基于Eclipse进行开发的, 不仅可以单独使用, 也可以作为插件的形式嵌入在Eclipse中使用

可以在 官网下载并使用

主要作用就是用来分析Dump文件的

MAT不是一个万能工具, 并不能处理所有类型的堆存储文件, 但是比较主流的如Sun, HP, SAP所采用的的hprof二进制堆存储文件, 已经IBM的PHD堆存储文件等都能被很好的解析

最最重要的功能是可以为开发人员生成内存泄漏报表, 方便定位问题和分析问题

内存分析 java mac java内存分析工具mat_方法调用

生成Dump文件

file->acquire heap dump -> 选择对应进程即可

MAT介绍

内存分析 java mac java内存分析工具mat_内存泄漏_02

分析Dump文件
histogram

展示各个类的实例数目以及这些实例的shallow heap(浅堆)和retained heap(深堆)的总和

内存分析 java mac java内存分析工具mat_内存泄漏_03

thread overview
  • 查看系统中的java进程
  • 查看局部变量的信息

内存分析 java mac java内存分析工具mat_存储文件_04

对象相互引用关系

内存分析 java mac java内存分析工具mat_方法调用_05

浅堆与深堆
  • shallow heap(浅堆):
  • 只一个对象所消耗的内存, 在32位系统中, 一个对象引用占4个字节, 一个int类型会占据4个字节, long类型占据8个字节, 每个对象头需要占用8个字节, 根据对快照格式不同, 对象的大小可能回想8字节对齐
  • 以String为例:
  • String类中有两个int变量,占8个字节, 一个对象引用变量占4个字节, 一个对象头占8个字节,总计20字节, 向8字节对齐,最后总大小为24字节(JDK7中)
  • 这24字节为String对象的浅堆大小, 与String的value值无关, 无论value的长度如何, 其浅堆始终为24自己
  • retained heap(深堆)
  • 指对象的保留集中所有的对象的浅堆大小之和
  • 保留集:
  • 对象A的保留集是指A被垃圾回收后, 可以被释放的所有的对象集合(包括对象A本身), 即对象A的保留集可以被认为是只能通过对象A被直接或间接访问到的所有对象的集合, 就是指对象A所持有的对象的集合

浅堆指对象本身占用的内存, 不包括其内部引用对象的大小, 一个对象的深堆值只能通过该对象访问到的所有对象的浅堆之和,即对象被回收后可以释放的真实空间

对象的实际大小:

对象的实际大小是一个对象所能触及的所有对象的浅堆大小之和, 与深堆并不相同

比如下图中, A.B.C.D.E五个对象, A引用了C.D, B引用看C.E, 那么A的浅堆大小只是A本身, A的实际大小是A.C.D三者之和, A的深堆大小为A.D, 由于C还可以通过B访问到, 所以C并不能算在A的深堆范围之内

内存分析 java mac java内存分析工具mat_内存分析 java mac_06

支配树

支配树的概念源自于图论

MAT提供了一个称为支配树的对象图, 体现了对象实例间的支配关系, 在对象引用图中所有执行B的路径都经过对象A, 则认为对象A支配对象B, 如果对象A是离对象B最近的一个 支配对象, 则认为对象A为对象B的直接支配者, 支配树是基于对象间的引用图所建立的,具有以下基本特征

  • 对象A的子树(所有被对象A支配的对象集合)表示对象A的保留集即深堆
  • 如果A支配B,那么A的直接支配者也支配B
  • 支配树的边与对象引用图的边不直接对应

内存分析 java mac java内存分析工具mat_存储文件_07

JProfiler

概述

JProfiler是ej-technologies公司开发的一款Java应用性能诊断工具, 功能强大, 但是收费

官网地址

  • 特点:
  • 使用方便,界面操作友好
  • 对被分析的应用小
  • CPU, Thread, Memory分析功能尤其强大
  • 支持对jdbc, noSql, jsp, servlet, socket等进行分析
  • 支持多种模式(在线, 离线)分析
  • 支持监控本地, 远程的JVM
  • 跨平台, 拥有多种操作系统的安装版本
  • 主要功能
  • 方法调用
  • 对方法调用的 分析可以帮助了解应用程序 正在做什么, 并找到提高其性能的方法
  • 内存分配
  • 通过分析堆上对象, 引用链和垃圾收集可以帮助修复内存泄漏问题, 优化内存使用
  • 线程和锁
  • 提供多种针对线程和锁的分析视图帮助发现线程问题
  • 高级子系统
  • 许多性能问题都发生在更高的语义级别上, 例如, 对JDBC的调用, 可以找出执行最慢的SQL语句, JProfiler支持对这些子系统进行集成分析
安装

客户端安装直接去官网下载安装即可

  • JProfiler中配置IDEA(11.0版本需要下面的步骤,11.1.4版本的不需要,只需要在IDEA中安装好插件即可)

Session-> IDE Integrations

内存分析 java mac java内存分析工具mat_方法调用_08

选择IDEA

内存分析 java mac java内存分析工具mat_内存泄漏_09

点击Integrate-> Proceed

内存分析 java mac java内存分析工具mat_存储文件_10

在C:/User下找到IDEA的一个隐藏目录选择

内存分析 java mac java内存分析工具mat_jvm_11

配置完成

内存分析 java mac java内存分析工具mat_内存分析 java mac_12

  • IDEA配置启动JProfiler

IDEA中启动JProfiler只需要在Plugins里面搜索JProfiler安装插件

内存分析 java mac java内存分析工具mat_jvm_13

安装完成后, 在settings->tools-> JProfiler 设置启动JProfilr程序路径

内存分析 java mac java内存分析工具mat_jvm_14

IDEA启动选项会出现如下图标, 需要JProfiler检测时, 使用该启动方式启动即可

内存分析 java mac java内存分析工具mat_方法调用_15

使用

内存分析 java mac java内存分析工具mat_方法调用_16

两种数据采集方式
  • Instrumentation 重构模式
  • JProfiler全功能模式, 在class加载之前, JProfiler把相关功能代码写入到需要分析的class的bytecode中.对正在运行的jvm有一定影响
  • 优点: 功能强大, 调用的堆栈信息是准确的
  • 缺点: 若要分析的 class比较多, 则对应用的性能影响较大, CPU开销可能很高,(取决于Filter的控制), 因此此模式一般配合Filter使用, 只对特定的类或包进行分析
  • Sampling 抽样模式
  • 类似于样本统计, 每个一定时间(5ms)将每个线程中方法栈中的信息统计出来
  • 优点: 对CPU开销非常低, 对应用影响小,
  • 缺点: 一些数据不能提供, 如方法的调用次数, 执行时间等

JProfiler本身没有指出数据的采集类型, 这里的采集类型是针对方法调用的采集类型, 因为JProfiler的绝大多数核心功能都依赖于方法调用采集的数据, 所以可以直接认为是JProfiler的数据采集类型

一般情况下选择Sampling 模式就足够了,这个也是推荐使用的模式, 其他不需要做任何调整, 使用默认的就可以了

内存分析 java mac java内存分析工具mat_内存分析 java mac_17

内存分析 java mac java内存分析工具mat_方法调用_18

遥感监测

内存分析 java mac java内存分析工具mat_方法调用_19

可以点击左侧去查看各个条目详细情况

内存分析 java mac java内存分析工具mat_jvm_20

内存分析 java mac java内存分析工具mat_内存泄漏_21

内存视图
  • All Objects

内存分析 java mac java内存分析工具mat_jvm_22

内存分析 java mac java内存分析工具mat_内存泄漏_23

关注的点:

Size大,数量多->频繁创建的Java对象 -> 死循环, 循环次数过多

Size大,数量不多->存在大的对象-> 读取文件时, byte[] 应该边读边写

存在内存泄漏-> 可以从内存角度查看每次垃圾回收完后的最低点是否成线性关系, 如果是,那么很有可能存在 内存泄漏

之后配合Record Objects进行分析

如果存在一直活跃,且没有被回收过的对象, 那么就很有可能是内存泄漏的原因了

内存分析 java mac java内存分析工具mat_方法调用_24

  • Record Objects

内存分析 java mac java内存分析工具mat_内存泄漏_25

  • Allocation Call Tree

内存分析 java mac java内存分析工具mat_存储文件_26

  • Allocation Hot Spots

内存分析 java mac java内存分析工具mat_方法调用_27

  • Class Tracker

内存分析 java mac java内存分析工具mat_jvm_28

堆遍历

可以生成对快照或者对转储文件

内存分析 java mac java内存分析工具mat_内存泄漏_29

CPU视图

内存分析 java mac java内存分析工具mat_内存泄漏_30

线程视图

内存分析 java mac java内存分析工具mat_方法调用_31

主要关三个方面:

  1. web容器的线程最大数, 比如Tomcat的线程容量应该略大于并发数
  2. 线程阻塞
  3. 线程死锁

都可以在History中看到

监视器&锁

内存分析 java mac java内存分析工具mat_方法调用_32