Memory Analyzer使用

​ 记录 Memory Anallyzer Tool 相关概念与使用。

1. 名词概念解释

1.1 Shallow heap && Retained Heap

shallow是浅的意思,比如,一个ArrayList的浅占用仅仅是size,elementData[],modCount三个成员对象16个字节,加上引用8个字节,总共是24个字节。但是elementData才是冰山下的大头。retained直译是保留的意思,指的是某个对象所持有的所有对象(直接和间接)。某种意义上来说,reatined heap才是我们更加关注的对象。

1.2 Dominator Tree

Dominator Tree就是对象关系树,一个对象的所有子支配树对象,就是上面所说的retained heap。

1.3 Path to GC Roots

通过分析gc roots可以确定某些对象无法回收的原因。

1.4 Outgoing references && Incoming references

目标对象x,如果要查询x引用了谁,那么就是前者,如果要看x被谁引用,那么就是后者。

1.5 Garbage Collection Roots

GC Roots是一个能被GC Roots是一个能被堆访问到的对象,下面是几种GC Roots:
堆访问到的对象,下面是几种GC Roots:

  • System Classes 系统加载的类
  • JNI Local native 代码的本地栈帧
  • JNI Global
  • Thread Block 被一个活跃中的线程引用的对象
  • Busy Monitor 锁
  • Java Local 本地栈帧变量
  • Native Stack native代码的本地栈帧
  • Finalizable 正在等待执行finalize()方法的队列

2. 界面常用操作

main_interface

打开一个dump下的堆内存界面如上,3819.heapdump下的8个图标分别含义分别如下:

  • open overview panel 打开概述界面,图片里的就是概述界面。
  • create a histogram from an arbitrary set of objects 打开对象统计界面
  • open dominator tree for entire heap 打开对象关系树状图(类似于tree命令)
  • open object query language studio 执行OQL查询
  • show thread stack 展示线程堆栈
  • run expert system test 运行自动检测内存泄漏等功能
  • open query browser 打开查询界面,查询某个对象的被引用,引用对象等,必须指定一个对象
  • find object by address 通过一个内存地址查询对象

3. Overview页面操作

当我们拿到一个heapdump并导入堆栈的时候,确保我们的内存大于heapdump文件,并且检查一下MemoryAnalyzer.ini文件,确保最大堆内存大于我们的heapdump文件。
解析完heapdump,直接打开overview,会有步骤建议如下:
overview_action

3.1 actions
  • Histogram:会打开所有的对象统计,可以按对象数量,shallow memory, retained memory排序
  • Dminator Tree:直接展示支配树,一样可以按上面的几个条件排序
  • Top Consumers:直接查看最耗费内存(retained heap)的的对象
  • Duplicate Classes:检测重复加载的Class
3.2 reports
  • Leak Suspects:泄漏检测,运行这个选项直接会给出可能的内存泄漏点
  • Top Components:分析占用内存最高的的组件

4. Object Query Language

OQL语法类似SQL,下面是基本语法:

1
2
3
4
SELECT *
FROM [ INSTANCEOF ] <class name="name">
[ WHERE <filter-expression> ]
</filter-expression></class>

举个栗子,访问ArrayList中数组长度大于等于5的对象和他的所有持有的引用:

1
2
3
SELECT as retained set * 
from java.util.ArrayList list
where list.elementData != null and list.elementData.@length >= 5

select如果加上AS RETAINED SET,将查询所有持有的引用。
from可以是objectAddress,objectId,className,或者是子查询的结果。
如果是一个对象的field,直接通过.的方式即可访问,使用.@访问MAT构建的JavaBean属性,这些属性如下:

属性名 属性含义
objectId 对象id
objectAddress 地址id
clazz class对象
usedHeapSize 浅堆
retainedHeapSize 保留堆
displayName 类名 + 地址名
classLoaderIds loaderId
length 数组的长度
valueArray primitive数组的内容 .@valueArray[index]
referenceArray 引用数组的内容,使用方式同上

还有一些复杂的用法还不是很清楚,待探索。另外,上述所有的参考资料,可以直接从Memory Analyzer的Help->Help contents里面的文档查看,或者浏览器直接访问参考资料里的地址。

参考资料

Memory Analyzer