Android性能优化第(三)篇---MAT比Menmery Monitor更强大


Android性能优化第(一)篇---基本概念中讲了JAVA的四大引用,讲了一下GCRoot,第二篇 Memory Monitor检测内存泄露仅仅说了Menmery Monitor的使用,这篇博客谈一下MAT来寻找内存泄露,相对来说, Memory Monitor没有MAT强大,但是在开始介绍MAT之前,上两篇没有说清楚的问题先说一下。

  • GC回收对可回收对象的判定
    什么样的对象是可以被回收的?
    当然是GC发现通过任何referencechain(引用链)无法访问某个对象的时候,该对象即被回收。名词GC Roots正是分析这一过程的起点,例如JVM自己确保了对象的可到达性(那么JVM就是GC Roots),所以GCRoots就是这样在内存中保持对象可到达性的,一旦不可到达,即被回收。通常GC Roots是一个在current thread(当前线程)的call stack(调用栈)上的对象(例如方法参数和局部变量),或者是线程自身或者是system class loader(系统类加载器)加载的类以及native code(本地代码)保留的活动对象。所以GC Roots是分析对象为何还存活于内存中的利器。

GC Root Tracing算法,对于可回收对象的判定

上面这段话,也写出了 检测内存泄露的基本思想以”GC Roots”的对象作为起始点向下搜索,搜索形成的路径称为引用链,当一个对象到GC Roots没有任何引用链相连(即不可达的),则该对象被判定为可以被回收的对象,反之不能被回收。也写出了 内存泄露的原因对象无用了,但仍然可达(未释放),垃圾回收器无法回收。

好啦,下面开始介绍MAT,MAT工具全称为Memory Analyzer Tool,(MAT下载:http://eclipse.org/mat/downloads.php)是一款详细分析Java堆内存的工具,该工具非常强大,为了使用该工具,我们需要hprof文件。但是该文件不能直接被MAT使用,需要进行一步转化,可以使用hprof-conv命令来转化,但是AndroidStudio可以直接转化。

导出标准的hprof文件

然後用MAT打开我们导出的文件,我导出了两个文件,test1.hprof和test2.hprof,其中test1.hprof是内存未泄露时的快照,test2.hprof是内存已经泄露的快照。我们用MAT的Histogram(直方图)和Dominator Tree (支配树)来分析内存情况。Histogram可以列出内存中每个对象的名字、数量以及大小。Dominator Tree会将所有内存中的对象按大小进行排序,并且我们可以分析对象之间的引用结构。
MAT工具主界面

一、 Histogram(直方图)

可列出每一个类的实例数。支持正则表达式查找,也可以计算出该类所有对象的retained size。默认是通过class(group by class)分类展示的。


直方图.png

这就是test2.hprof的直方图。现在要说两个名词解释。Shallow Heap/Retained Heap

  • Shallow Heap
    Shallow size就是对象本身占用内存的大小,不包含其引用的对象内存,实际分析中作用不大。在堆上,看起来是一堆原生的byte[], char[], int[],对象本身的内存都很小。所以我们可以看到以Shallow Heap进行排序的Histogram图中,排在第一位第二位的是byte,char
  • Retained Heap
    Retained size是该对象自己的shallow size,加上从该对象能直接或间接访问到对象的shallow size之和。换句话说,retained size是该对象被GC之后所能回收到内存的总和。RetainedHeap可以更精确的反映一个对象实际占用的大小(因为如果该对象释放,retained heap都可以被释放)。

Histogram中是可以显示对象的数量的,那么比如说我们现在怀疑MainActivity中有可能存在内存泄漏,就可以在第一行的正则表达式框中搜索“MainActivity”,如下所示:


可以看到MainActivity的数量是2,这不正常,解决这个,就需要查看MainActivity被谁引用了,不能被释放。我们右键选择exclude all phantom/weak/soft etc.references, 意思是查看排除虚引用/弱引用/软引用等的引用链 (这些引用最终都能够被GC干掉,所以排除)

还有其他菜单供选择

  • List objects with (以Dominator Tree的方式查看)
  • incoming references 引用到该对象的对象
  • outcoming references 被该对象引用的对象
  • Show objects by class (以class的方式查看)
  • incoming references 引用到该对象的对象
  • outcoming references 被该对象引用的对象

当你按上面操作之后,凶手就出现了,原来是UserManger的实例。


还有可以通过包名来查看Histogram。


还有更强大的,通过OQL语句查询,有点像写SQL语句。



是不是分分钟查出MainActivity有两个对象。哈哈!
比如:查找size=0并且未使用过的ArrayList

select * from java.util.ArrayList where size=0 and modCount=0

这个地方可以多研究研究。

二、Dominator Tree(支配树)

Dominator Tree是对象之间dominator关系树。如果从GC Root到达Y的的所有path都经过X,那么我们称X dominates Y,或者X是Y的Dominator Dominator Tree由系统中复杂的对象图计算而来。从MAT的dominator tree中可以看到占用内存最大的对象以及每个对象的dominator。 我们也可以右键选择Immediate Dominator”来查看某个对象的dominator。它可以将所有对象按照Heap大小排序显示, 这样大内存对象就是排在前几名的,我们可以搜索大内存对象通向GC Roots的路径,因为内存占用越高的对象越值得怀疑,使用方法跟Histogram(直方图)差不多,在这里我就不做过多的介绍了。

三、内存快照对比

我们可以将test1.hprof的直方图与test2.hprof的直方图对比来看,其中Object#0是test1.hprof的,Object#1是test2.hprof的,通过比较看哪一些对象的大小相差过大。


内存快照对比

其他资料:
官方的帮助文档
http://wiki.eclipse.org/index.php/MemoryAnalyzer

使用 Eclipse Memory Analyzer 进行堆转储文件分析
http://www.vogella.de/articles/EclipseMemoryAnalyser/article.html

MAT使用教程
http://www.vogella.de/articles/EclipseMemoryAnalyser/article.html

      </div>
    </div>
</div>

<!-- 如果是付费文章,未购买,则显示购买按钮 -->

<!-- 连载目录项 -->

<!-- 如果是付费文章 -->
  <!-- 如果是付费连载,已购买,且作者允许赞赏,则显示付费信息和赞赏 -->
    <div id="free-reward-panel" class="support-author"><p>小礼物走一走,来简书关注我</p> <div class="btn btn-pay">赞赏支持</div> <div class="supporter"><ul class="support-list"><li><a target="_blank" href="javascript:void(0)" class="avatar"><img src="//cdn2.jianshu.io/assets/default_avatar/2-9636b13945b9ccf345bc98d0d81074eb.jpg"></a></li></ul> <!----></div> <!----> <!----></div>

  <div class="show-foot">
    <a class="notebook" href="/nb/7754758">
      <i class="iconfont ic-search-notebook"></i>
      <span>Android性能优化</span>



  <!-- 文章底部作者信息 -->
    <div class="follow-detail">
      <div class="info">
        <a class="avatar" href="/u/ce54e5c21032">
          <img src="//upload.jianshu.io/users/upload_avatars/1836169/96da7b28-8952-4f7e-bcd1-a0ad6706d33e.jpg?imageMogr2/auto-orient/strip|imageView2/1/w/96/h/96" alt="96">


LooperJing
22d8d123 271c 4d80 9c59 6990844a9e37

写了 118592 字,被 5852 人关注,获得了 2796 个喜欢


About me:我是LooperJing,目前就职于小米,关注于app开发和framework,欢迎关注与私信,转载文章请注明出处!
<div class="meta-bottom">
  <div data-v-6ddd02c6="" class="like"><div data-v-6ddd02c6="" class="btn like-group"><div data-v-6ddd02c6="" class="btn-like"><a data-v-6ddd02c6="">喜欢</a></div> <div data-v-6ddd02c6="" class="modal-wrap"><a data-v-6ddd02c6="">37</a></div></div> <!----></div>
  <div class="share-group">
    <a class="share-circle" data-action="weixin-share" data-toggle="tooltip" data-original-title="分享到微信">
      <i class="iconfont ic-wechat"></i>
    </a>
    <a class="share-circle" data-action="weibo-share" data-toggle="tooltip" href="javascript:void((function(s,d,e,r,l,p,t,z,c){var%20f='http://v.t.sina.com.cn/share/share.php?appkey=1881139527',u=z||d.location,p=['&amp;url=',e(u),'&amp;title=',e(t||d.title),'&amp;source=',e(r),'&amp;sourceUrl=',e(l),'&amp;content=',c||'gb2312','&amp;pic=',e(p||'')].join('');function%20a(){if(!window.open([f,p].join(''),'mb',['toolbar=0,status=0,resizable=1,width=440,height=430,left=',(s.width-440)/2,',top=',(s.height-430)/2].join('')))u.href=[f,p].join('');};if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();})(screen,document,encodeURIComponent,'','','', '推荐 LooperJing 的文章《Android性能优化第(三)篇---MAT比Menmery Monitor更强大》( 分享自 @简书 )','https://www.jianshu.com/p/2d47d1cf5ccf?utm_campaign=maleskine&amp;utm_content=note&amp;utm_medium=reader_share&amp;utm_source=weibo','页面编码gb2312|utf-8默认gb2312'));" data-original-title="分享到微博">
      <i class="iconfont ic-weibo"></i>
    </a>
    <a class="share-circle" data-toggle="tooltip" id="longshare" target="_blank" data-original-title="" title="">
        <div class="qrcode" id="qrcode">
         <img src="//cdn2.jianshu.io/assets/web/download-index-side-qrcode-cb13fc9106a478795f8d10f9f632fccf.png" alt="Download index side qrcode">
         <p>下载app生成长微博图片</p>
         </div>
      <i class="iconfont ic-picture"></i>
    </a>
    <a class="share-circle more-share" tabindex="0" data-toggle="popover" data-placement="top" data-html="true" data-trigger="focus" href="javascript:void(0);" data-content="
      <ul class=&quot;share-list&quot;>
        <li><a href=&quot;javascript:void(function(){var d=document,e=encodeURIComponent,r='http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url='+e('https://www.jianshu.com/p/2d47d1cf5ccf?utm_campaign=maleskine&amp;utm_content=note&amp;utm_medium=reader_share&amp;utm_source=qzone')+'&amp;title='+e('推荐 LooperJing 的文章《Android性能优化第(三)篇---MAT比Menmery Monitor更强大》'),x=function(){if(!window.open(r,'qzone','toolbar=0,resizable=1,scrollbars=yes,status=1,width=600,height=600'))location.href=r};if(/Firefox/.test(navigator.userAgent)){setTimeout(x,0)}else{x()}})();&quot;><i class=&quot;social-icon-sprite social-icon-zone&quot;></i><span>分享到QQ空间</span></a></li>
        <li><a href=&quot;javascript:void(function(){var d=document,e=encodeURIComponent,r='https://twitter.com/share?url='+e('https://www.jianshu.com/p/2d47d1cf5ccf?utm_campaign=maleskine&amp;utm_content=note&amp;utm_medium=reader_share&amp;utm_source=twitter')+'&amp;text='+e('推荐 LooperJing 的文章《Android性能优化第(三)篇---MAT比Menmery Monitor更强大》( 分享自 @jianshucom )')+'&amp;related='+e('jianshucom'),x=function(){if(!window.open(r,'twitter','toolbar=0,resizable=1,scrollbars=yes,status=1,width=600,height=600'))location.href=r};if(/Firefox/.test(navigator.userAgent)){setTimeout(x,0)}else{x()}})();&quot;><i class=&quot;social-icon-sprite social-icon-twitter&quot;></i><span>分享到Twitter</span></a></li>
        <li><a href=&quot;javascript:void(function(){var d=document,e=encodeURIComponent,r='https://www.facebook.com/dialog/share?app_id=483126645039390&amp;display=popup&amp;href=https://www.jianshu.com/p/2d47d1cf5ccf?utm_campaign=maleskine&amp;utm_content=note&amp;utm_medium=reader_share&amp;utm_source=facebook',x=function(){if(!window.open(r,'facebook','toolbar=0,resizable=1,scrollbars=yes,status=1,width=450,height=330'))location.href=r};if(/Firefox/.test(navigator.userAgent)){setTimeout(x,0)}else{x()}})();&quot;><i class=&quot;social-icon-sprite social-icon-facebook&quot;></i><span>分享到Facebook</span></a></li>
        <li><a href=&quot;javascript:void(function(){var d=document,e=encodeURIComponent,r='https://plus.google.com/share?url='+e('https://www.jianshu.com/p/2d47d1cf5ccf?utm_campaign=maleskine&amp;utm_content=note&amp;utm_medium=reader_share&amp;utm_source=google_plus'),x=function(){if(!window.open(r,'google_plus','toolbar=0,resizable=1,scrollbars=yes,status=1,width=450,height=330'))location.href=r};if(/Firefox/.test(navigator.userAgent)){setTimeout(x,0)}else{x()}})();&quot;><i class=&quot;social-icon-sprite social-icon-google&quot;></i><span>分享到Google+</span></a></li>
        <li><a href=&quot;javascript:void(function(){var d=document,e=encodeURIComponent,s1=window.getSelection,s2=d.getSelection,s3=d.selection,s=s1?s1():s2?s2():s3?s3.createRange().text:'',r='http://www.douban.com/recommend/?url='+e('https://www.jianshu.com/p/2d47d1cf5ccf?utm_campaign=maleskine&amp;utm_content=note&amp;utm_medium=reader_share&amp;utm_source=douban')+'&amp;title='+e('Android性能优化第(三)篇---MAT比Menmery Monitor更强大')+'&amp;sel='+e(s)+'&amp;v=1',x=function(){if(!window.open(r,'douban','toolbar=0,resizable=1,scrollbars=yes,status=1,width=450,height=330'))location.href=r+'&amp;r=1'};if(/Firefox/.test(navigator.userAgent)){setTimeout(x,0)}else{x()}})()&quot;><i class=&quot;social-icon-sprite social-icon-douban&quot;></i><span>分享到豆瓣</span></a></li>
      </ul>
    " data-original-title="" title="">更多分享</a>
  </div>
</div>

  <a id="web-note-ad-2" target="_blank" href="/p/428251ede1aa"><img src="//cdn2.jianshu.io/assets/web/gupao-b953be49108805c4198258448895344a.jpg" alt="Gupao"></a>

<!--
<div id="note-comment-above-ad-container">
  <span id="youdao-comment-ad" class="ad-badge">广告</span>
</div>
-->
<div id="vue_comment"></div>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值