你的位置:首页 > 软件开发 > 操作系统 > MAT使用入门

MAT使用入门

发布时间:2016-04-12 22:11:27
原文出处: 高建武 (Granker,@高爷) MAT简介MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众 ...

原文出处: 高建武 (Granker,@高爷)   

MAT简介

MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。

MAT使用入门

 

MAT

当然MAT也有独立的不依赖Eclipse的版本,只不过这个版本在调试Android内存的时候,需要将DDMS生成的文件进行转换,才可以在独立版本的MAT上打开。不过Android SDK中已经提供了这个Tools,所以使用起来也是很方便的。

MAT工具的下载安装

这里是MAT的下载地址:https://eclipse.org/mat/downloads.php,下载时会提供三种选择的方式:

MAT使用入门

 

Download MAT
  • Update Site 这种方式后面会有一个网址:比如http://download.eclipse.org/mat/1.4/update-site/ ,安装过Eclipse插件的同学应该知道,只要把这段网址复制到对应的Eclipse的Install New Software那里,就可以进行在线下载了。MAT使用入门

     

    MAT with eclipse
  • Archived Update Site 这种方式安装的位置和上一种差不多,只不过第一种是在线下载,这一种是使用离线包进行更新,这种方式劣势是当这个插件更新后,需要重新下载离线包,而第一种方式则可以在线下载更新。
  • Stand-alone Eclipse RCP Applications 这种方式就是把MAT当成一个独立的工具使用,不再依附于Eclipse,适合不使用Eclipse而使用Android Studio的同学。这种方式有个麻烦的地方就是DDMS导出的文件,需要进行转换才可以在MAT中打开。

下载安装好之后,就可以使用MAT进行实际的操作了。

Android(Java)中常见的容易引起内存泄露的不良代码

使用MAT工具之前,要对Android的内存分配方式有基本的了解,对容易引起内存泄露的代码也要保持敏感,在代码级别对内存泄露的排查,有助于内存的使用。

Android主要应用在嵌入式设备当中,而嵌入式设备由于一些众所周知的条件限制,通常都不会有很高的配置,特别是内存是比较有限的。如果我们编写的代码当中有太多的对内存使用不当的地方,难免会使得我们的设备运行缓慢,甚至是死机。为了能够使得Android应用程序安全且快速的运行,Android的每个应用程序都会使用一个专有的Dalvik虚拟机实例来运行,它是由Zygote服务进程孵化出来的,也就是说每个应用程序都是在属于自己的进程中运行的。一方面,如果程序在运行过程中出现了内存泄漏的问题,仅仅会使得自己的进程被kill掉,而不会影响其他进程(如果是system_process等系统进程出问题的话,则会引起系统重启)。另一方面Android为不同类型的进程分配了不同的内存使用上限,如果应用进程使用的内存超过了这个上限,则会被系统视为内存泄漏,从而被kill掉。

常见的内存使用不当的情况

  • 查询数据库没有关闭游标 Cursor cursor = getContentResolver().query(uri ...); Cursor cursor = null;
  • 构造Adapter时,没有使用缓存的 convertView public View getView(int position, View convertView, ViewGroup parent) public View getView(int position, View convertView, ViewGroup parent) {

    示例修正代码:

      public View getView(int position, View convertView, ViewGroup parent) {

    关于ListView的使用和优化,可以参考这两篇文章:

    • Using lists in Android (ListView) – Tutorial Bitmap bitmap ;
    • 释放对象的引用 public class DemoActivity extends Activity {

      我们有一个成员变量 obj,在operation()中我们希望能够将处理obj实例的操作post到某个线程的MessageQueue中。在以上的代码中,即便是mHandler所在的线程使用完了obj所引用的对象,但这个对象仍然不会被垃圾回收掉,因为DemoActivity.obj还保有这个对象的引用。所以如果在DemoActivity中不再使用这个对象了,可以在[Mark]的位置释放对象的引用,而代码可以修改为:

        public void operation() {

      示例B:

      选择存储路径保存后就可以得到对应进程的HPROF文件。eclipse插件可以把上面的工作一键完成。只需要点击Dump HPROF file图标,然后MAT插件就会自动转换格式,并且在eclipse中打开分析结果。eclipse中还专门有个Memory Analysis视图 ,得到对应的文件后,如果安装了Eclipse插件,那么切换到Memory Analyzer视图。使用独立安装的,要使用Android SDK自带的的工具(hprof-conv 位置在sdk/platform-tools/hprof-conv)进行转换

        hprof-conv xxx.xxx.xxx.hprof xxx.xxx.xxx.hprof

      转换过后的.hprof文件即可使用MAT工具打开了。

      使用Android Studio获取HPROF文件

      使用Android Studio同样可以导出对应的HPROF文件:

      MAT使用入门

       

      Android-Studio

      最新版本的Android Studio得在文件上右键转换成标准的HPROF文件,在可以在MAT中打开。

      MAT主界面介绍

      这里介绍的不是MAT这个工具的主界面,而是导入一个文件之后,显示OverView的界面。

      1. 打开经过转换的hprof文件:MAT使用入门

         

        open hprof

        如果选择了第一个,则会生成一个报告。这个无大碍。

        MAT使用入门

         

        Leak Suspects
      2. 选择OverView界面:MAT使用入门

         

        System OverView

        我们需要关注的是下面的Actions区域

        • Histogram:列出内存中的对象,对象的个数以及大小MAT使用入门

           

          Histogram
        • Dominator Tree:列出最大的对象以及其依赖存活的Object (大小是以Retained Heap为标准排序的)
        MAT使用入门

         

        Dominator Tree
        • Top Consumers : 通过图形列出最大的objectMAT使用入门

           

          Top Consumers
        • Duplicate Class:通过MAT自动分析泄漏的原因

      一般Histogram和 Dominator Tree是最常用的。

      MAT中一些概念介绍

      要看懂MAT的列表信息,Shallow heap、Retained Heap、GC Root这几个概念一定要弄懂。

      Shallow heap

      Shallow size就是对象本身占用内存的大小,不包含其引用的对象。

      • 常规对象(非数组)的Shallow size有其成员变量的数量和类型决定。
      • 数组的shallow size有数组元素的类型(对象类型、基本类型)和数组长度决定

      因为不像c++的对象本身可以存放大量内存,java的对象成员都是些引用。真正的内存都在堆上,看起来是一堆原生的byte[], char[], int[],所以我们如果只看对象本身的内存,那么数量都很小。所以我们看到Histogram图是以Shallow size进行排序的,排在第一位第二位的是byte,char 。

      Retained Heap

      Retained Heap的概念,它表示如果一个对象被释放掉,那会因为该对象的释放而减少引用进而被释放的所有的对象(包括被递归释放的)所占用的heap大小。于是,如果一个对象的某个成员new了一大块int数组,那这个int数组也可以计算到这个对象中。相对于shallow heap,Retained heap可以更精确的反映一个对象实际占用的大小(因为如果该对象释放,retained heap都可以被释放)。

      这里要说一下的是,Retained Heap并不总是那么有效。例如我在A里new了一块内存,赋值给A的一个成员变量。此时我让B也指向这块内存。此时,因为A和B都引用到这块内存,所以A释放时,该内存不会被释放。所以这块内存不会被计算到A或者B的Retained Heap中。为了纠正这点,MAT中的Leading Object(例如A或者B)不一定只是一个对象,也可以是多个对象。此时,(A, B)这个组合的Retained Set就包含那块大内存了。对应到MAT的UI中,在Histogram中,可以选择Group By class, superclass or package来选择这个组。

      为了计算Retained Memory,MAT引入了Dominator Tree。加入对象A引用B和C,B和C又都引用到D(一个菱形)。此时要计算Retained Memory,A的包括A本身和B,C,D。B和C因为共同引用D,所以他俩的Retained Memory都只是他们本身。D当然也只是自己。我觉得是为了加快计算的速度,MAT改变了对象引用图,而转换成一个对象引用树。在这里例子中,树根是A,而B,C,D是他的三个儿子。B,C,D不再有相互关系。把引用图变成引用树,计算Retained Heap就会非常方便,显示也非常方便。对应到MAT UI上,在dominator tree这个view中,显示了每个对象的shallow heap和retained heap。然后可以以该节点位树根,一步步的细化看看retained heap到底是用在什么地方了。要说一下的是,这种从图到树的转换确实方便了内存分析,但有时候会让人有些疑惑。本来对象B是对象A的一个成员,但因为B还被C引用,所以B在树中并不在A下面,而很可能是平级。

      为了纠正这点,MAT中点击右键,可以List objects中选择with outgoing references和with incoming references。这是个真正的引用图的概念,

      • outgoing references :表示该对象的出节点(被该对象引用的对象)。
      • incoming references :表示该对象的入节点(引用到该对象的对象)。

      为了更好地理解Retained Heap,下面引用一个例子来说明:

      把内存中的对象看成下图中的节点,并且对象和对象之间互相引用。这里有一个特殊的节点GC Roots,这就是reference chain(引用链)的起点:

      MAT使用入门

       

      Paste_Image.pngMAT使用入门

       

      Paste_Image.png

      从obj1入手,上图中蓝色节点代表仅仅只有通过obj1才能直接或间接访问的对象。因为可以通过GC Roots访问,所以左图的obj3不是蓝色节点;而在右图却是蓝色,因为它已经被包含在retained集合内。

      Group

      在Histogram和Domiantor Tree界面,可以选择将结果用另一种Group的方式显示(默认是Group by Object),切换到Group by package,可以更好地查看具体是哪个包里的类占用内存大,也很容易定位到自己的应用程序。

      MAT使用入门

       

      Group

      Path to GC Root

      在Histogram或者Domiantor Tree的某一个条目上,右键可以查看其GC Root Path:

      MAT使用入门

       

      Path to GC Root

      这里也要说明一下Java的引用规则:

      参考文档

        1. Shallow and retained sizes
        2. MAT的wiki:http://wiki.eclipse.org/index.php/MemoryAnalyzer
        3. http://cxy.liuzhihengseo.com/529.html  QQ技术交流群290551701

      原标题:MAT使用入门

      关键词:

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。

可能感兴趣文章

我的浏览记录