紧接上篇文章,在上篇中我们使用了jhat命令分析了java heapdump信息。
但是在实际的问题分析中,尤其是OOM、内存泄漏等情况的分析中,Eclipse Memory Analyzer这个工具更适合。
1.准备工作下载工具地址:http://www.eclipse.org/mat/downloads.php
准备一个humpdump文件,笔者使用上一篇博客中heapdump.phrof来分析
2.Eclipse Memory Analyzer工具初见在File -> Open File中,打开我们的phrof文件, 进入主界面,如下所示:
我们从上到下来分析下主界面中的这几项内容
1.1 Details统计当前堆内存已经使用的大小明细信息。
1.2 Biggest Objects by Retained Size代表当前应用中占用内存最大的几个对象的统计信息。
在饼状图上点击,可以展示对应的加载类信息
1.3 Actions支持的操作
1.3.1 Histogram
应用中各个类所占用的内存直方图,以倒序排列。后续我们会继续分析该视图。
1.3.2 Dominator Tree
按照占用内存大小,将对象倒序排列。后续继续分析
1.3.3 Top Consumers
分析应用中资源消耗最高的对象(Biggest Object)、类(Biggest Top-Level Dominator Classes)、类加载器(Biggest Top-Level Dominator Class Loaders)及包(Biggest Top-Level Dominator Packages)
1.3.4 Duplicate Classes
发现被不同类加载器重复加载的类。
1.4 Reports1.4.1 Leak Suspects
内存泄露分析,这里会给出一个比较详细的展示图,后续分析
1.4.2 Top Components
展示内存占用大于1%的组件
下面我们通过实例来展示下各项内容
2.Histogram按照类维度来展示类的相关实例的内存使用。点击进入,如下图所示:
名词释义:
Shallow Heap:当前对象所占用的内存空间
Retained Heap:当前对象被回收后所能释放的内存空间
所以从上图能看到:byte[]数组占用的内存最大,我们可以在byte[]这一行,点击右键,会出现以下两列
名词释义:
List objects -> with outgoing references 当前对象包含了哪些对象
List objects -> with incoming references 当前对象被哪些对象包含
既然分析内存,那么我们可以使用 with incoming references来展示下被哪些对象包含
很容易看出,有10个byte[]占用内存比较大(每个byte[]为10M)
点开0xf868bd98对象(第一个byte[]),可以看到是哪个对象在引用当前数组,正式我们的User.java,这个正好与我们在代码中创建的byte[]数组是一样大的
3.Dominator tree从对象的角度来列举哪些比较占内存
点击该项后,进入如下界面:
肉眼可见的,JvmTest类占用内存最多,percentage为81.78%,点开之后,可以看到具体是哪些对象占用内存最多
一层层点开之后,还是我们的User对象中的byte[]占用内存最大,同2中的分析结果
4.Top Consumer展示消耗内存最大的对象饼状图
这个没什么可说的,跟2和3中的分析结果是一致的,就是展示更形象而已。
5.Leak Suspects内存泄漏分析,最重要的就是这个了。本项相当于是个总体说明,如果有内存泄露,直接看这项即可
报告中指出JvmTest这个类占用了81.78%的内存,有可能发生了内存泄露。
而JvmTest中有哪些占用内存比较高的元素呢,在Accumulated Objects in Dominator Tree有所展示。
点击HashMap$Node项,List objects -> with outgoing references,查看下Node中有什么元素
同样,还是User对象中的byte[]数组比较占用内存
总结:到这里差不多就把heapdump分析过程中需要关注的点讲解完成。
多实战,多用工具,没有解决不了的问题。