使用MAT分析Java内存

摘要:
OverviewMAT是一个JAVA标头分析器,可用于分析内存泄漏并减少内存消耗。分析Processshowmap中/dev/ashmem/dalvik堆项目占用的内存。请参考我写的关于使用showmap分析系统内存使用情况的文章。接下来,我们将讨论如何使用EclipseMAT来分析Android应用程序的内存消耗。dumpHprof键可以立即转储Hprof文件。直方图可以看到所有实例的分配,DominatorTree列出了堆中最大的对象。LeakSuspects主要列出疑似内存泄漏。在下图中,MAT工具怀疑第一个问题存在1.5M内存泄漏:然后,第一个问题的描述列出了一些大型示例。

Overview

MAT(Memory Analyzer Tool) 是一个JAVA Heaper分析器,可以用来分析内存泄露和减少内存消耗。分析Process showmap中的/dev/ashmem/dalvik-heap(deleted)一项所占用的Memory.可以参考我写的使用showmap分析系统内存占用情况一文。


下面就将一下如何使用Eclipse MAT分析Android应用程序内存的消耗。所需要的是已经安装ADT和SDK的Eclipse.然后可以在http://www.eclipse.org/mat/ 下载MAT插件将MAT安装在Eclipse上。

如下图所示,手机连接电脑,打开Eclipse,进入DDMS中,选择一个进程,可以看到下面的

画面:

使用MAT分析Java内存第1张

update Heap键的作用是立即更新,使工具可以获得手机上运行的Android应用程序的最新Heap分配状况。dump Hprof键则可以立即dump Hprof文件(Java Heap 分配信息存储在Hprof文件中)。 Cause GC键主要就是强制引发一次GC(垃圾回收)。

点击dump Heap键,我们会看到如下画面:

使用MAT分析Java内存第2张

这个就是Eclipse中Hprof文件分析界面的主页面了。

其中Histogram可以看到所有实例的分配情况, Dominator Tree列出了堆的最大对象。 Leak Suspects主要是列出怀疑的内存泄露处。

Histogram

首先,我们来看一下Histogram,使用MAT分析Java内存第3张

这个列出了所有实例类型,右键选中实例类型Byte,选择Merge Shortest Paths to GC Root,然后选择excluse all phantom/weak/soft etc refereneces. Merge Shortest Paths to GC Root主要显示最短离GC Root的路径。Java的垃圾回收机制简单来说有点类似树的深度遍历方式,如果一个对象有引用,则GC Root到这个对象之间是有路径可达的。如果GC Root到 这个对象之间无任何路径可达,则这个对象是不可触及的,是可以回收的。exclude all phantom/weaker/soft etc references则是排除虚引用,弱引用及软引用。因为这些引用一般是可以回收的。 (详细解释请参考深入Java虚拟机 垃圾回收一章)。

然后可以可以看到如下画面:

使用MAT分析Java内存第4张

其中可以看到Resources类中有个sPreloadedDrawables的LongSparseArray对象,sPreloadedDrawables中有个mValues的Object数组,数组第139个个元素是一个NiePatchDrawable的对象,这个对象有个mNinePatch的对象,mNinePatch则有一个mChunk的Byte数组的引用。

可能大家已经注意到图中有个Shallow heap和Retained Heap, 具体代表什么意思呢?简单来讲,Shallow Heap Size是对象自身占用的Size。 Retained Heap Size是对象自身的Shallow Size +对象直接引用或者间接引用的对象的Shallow Size。

然后结合代码可以分析出来这个Byte数组是如何引用的,以及这个Byte数组是什么时候创建和销毁的,其创建和销毁是否是合理的。

假如说上面对象此时本来应该是被GC掉的,那么我们应该如何处理了。简单的办法就是将其中的某处置为null或者remove掉,使其到GC Root无路径可达,处于不可触及状态,垃圾回收器就可以回收了。

由于有很多对象,为了分析方便,我们可以点击Cause GC键使其强制发生一次GC,这样可以减少对象的个数,便于我们分析。

Leak Suspects

Leak Suspects列出了工具怀疑的内存泄露点。

在下图中,MAT工具怀疑第一个问题有1.5M的内存泄露:

使用MAT分析Java内存第5张

然后接着,是问题一的描述,列出了一些比较大的实例。

使用MAT分析Java内存第6张

点击Details可以看到细节信息。

使用MAT分析Java内存第7张

不过工具怀疑的也未必真的是存在的,但提供了一种参考。

参考:http://help.eclipse.org/kepler/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html

http://www.eclipse.org/mat/about/screenshots.php

        http://plumbr.eu/blog/how-much-memory-do-i-need-part-2-what-is-shallow-heap

        http://joeylittlefat.diandian.com/post/2011-09-27/5340625

免责声明:文章转载自《使用MAT分析Java内存》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇HTTP中的摘要认证机制Selenium基本使用(十一)异常捕获下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

使用antd Table + mobx 处理数组 出现的一系列问题

在store中定义了一个数组: @observable list = [...] 若是在table组件中直接使用list: <Table className={styles.table} columns={this.columns} dataSource={list}  /> 这时就会提示以下错误...

iOS开发OC基础:OC数组对象NSArray的常用方法

本文介绍了OC的数组对象的基本方法的使用: 因为OC的数组中存储的为对象类型,所以我们可以新建一个Person类,通过Person生成对象进行操作。 其中Person.h中的代码为: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #import @interface Person : NSObject {     NSStri...

JSDOM获取子节点的一些方法

一般情况获取子节点,通过找到查找父节点的ID或者class类名,来获取父节点,再通过children属性,得到子节点的数组; 之前在另外一篇随笔中说过,如果使用另一个属性childNode,会把注释、空文本、非空文本、标签都当做子节点,所以不要使用childNode属性。 var father = document.getElementById("ID名"...

jmeter_上一请求的响应值作为下一请求的参数

Json响应格式 json串中{}表示对象,[]表示数组 JSON Extractor使用jsonpath表达式匹配,可以一次取多个变量值。 $表示响应的根对象。 取子对象或对象的属性用. 取数组里的对象用[],数组索引从0开始。 获取数组的所有值$[*].属性 1)新建一个请求,返回json响应格式的,分析响应结果 1)在上一请求上点...

php中对象转换数组与数组转换对象实例

用stdClass转换数组为对象                                                                                  Php代码 $arr = array(); $arr['a'] = 1;...

matlab中imread 从图形文件读取图像

来源:https://ww2.mathworks.cn/help/matlab/ref/imread.html?searchHighlight=imread&s_tid=doc_srchtitle imread 从图形文件读取图像 全页折叠 语法 A = imread(filename) A = imread(filename,fmt) A...