使用MAT分析android项目内存泄露总结

来源:互联网 发布:htpc直播软件 编辑:程序博客网 时间:2024/06/06 17:36

MAT是个十分强大的内存分析工具,集成在ADT DDMS中。

1.Update Heap查看进程内存情况

点击这个图标,再点击下方”Cause GC"按键

上图中,HeapSize就是虚拟机的堆大小,Allocated就是已使用内存大小;

而下面的表格中,"data object"是进程中所有对象的总数和占用内存的总大小,"1-byte array(byte[], boolean[])"用来查看bitmap的C层内存占用情况,这两项是检测程序内存泄露的最重要的指标,当单个activity或fragment反复进出,这两项数据保持上升而不恢复,那就可能就是这activity或fragment有泄露了。



2.MAT使用实例

下面是一个内存泄露的例子:

主Activity:

public class TestActivity extends Activity{private String str1 = "123";        private String str2 = "456";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_test);TestClass.getInstance().setString(str1 );}}


测试class:

public class TestClass {public static TestClass mInstance;public static String mString;private TestClass(){}public static TestClass getInstance(){if(mInstance==null){mInstance = new TestClass();}return mInstance;}public void setString(String str){mString = str<span style="font-family: Arial, Helvetica, sans-serif;">;</span>}}
可以看到,TestActivity创建时把成员变量str传递给外部类,并被TestClass静态变量mString引用保存起来,当TestActivity要关闭时,因为其成员被外部类TestClass引用,所以无法销毁TestActivity,从而导致内存泄露。


下面就用MAT去分析:
(1)反复进出TestActivity 2次,点击"Dump HPROF file"图标,把hprof文件dump下来并通过MAT解析文件



(2)hprof文件解析并显示如下:


中间的饼状图统计了进程中内存的主要分配情况,不同的颜色碎块标注的是占了较多内存的类,而分析用到的主要是下述用到的选项:

Histogram —— 列出每个类的实例数量和内存占用情况

Dominator Tree —— 从大到小列出对象及其内存占用情况

Leak Suspects —— 统计内存泄露怀疑的部分(主要是分析哪些是内存大量堆积的实例)


(3)本例子中因为TestActivity占用内存较少,所以Leak Suspects模块难以有效快速地找出泄露点,因此这里我们进入Histogram模块,并搜索TestActivity,结果如下:


可以看到这类存在了2个TestActivity,这就是意味着第一次启动的TestActivity未完全销毁。右键弹出菜单,选择“List Objects—>with outgoing reference”就会列出这个类的所有实例及其相关实例(成员变量等)。


推理逐个查找,直至找到怀疑的对象str1,并右键选择“List Objects—>with incoming reference”,显示如下:


这里就看到了我们的str1被TestClass.mString变量引用了,至此我们就找到了泄露的点了,可以执行相应的解决方案了。




PS:初步使用MAT,以此作为总结文档,若有勘误,欢迎各位指正(图片上传不了。。。。。。。)

0 0
原创粉丝点击