转载请注明地址:http://blog.csdn.net/yincheng886337/article/details/50524890

MAT工具使用

理解相关概念

在了解MAT工具之前,我们需先对以下几个概念有所认知:

1)强引用、弱引用、软引用、虚引用

2)Shallow Size、Retained Size、Heap Size和Allocated

MAT工具实战

看完1)、2)两篇博客,相信大家此时对几个概念已具备了一定认知,下面就进入正题MAT工具的使用,说到MAT工具(Memory Analyzer Tool),首先是工具的获取与安装。

MAT工具获取路径:http://download.eclipse.org/mat/1.5/update-site/

MAT安装步骤详情请自行百度

安装好工具后,就需要去获取hprof文件,如果独立版的MAT,需采用hprof-conv <源文件> <目标文件> 命名进行转换。

下面以Android Studio dump操作示例:

步骤1:

图1.抓取hprof文件

步骤2:

图2.转换hprof文件

抓好hprof文件后,采用MAT打开hprof文件后,看到的界面如下图:

图3.MAT的overview图

有了MAT和hprof文件,且功能正常,马上进入MAT分析内存阶段。采用MAT进行内存分析主要分析以下几点:

1.程序是否内存泄露;

2.程序中大对象的占用是否合理;

3.程序中部分对象产生内存是否可以优化;

有了分析的目标,我们就开始朝着目标开始分析:

方法1:根据Leak Suspects快速查看泄露的可疑点

Step1:进入Leak Suspects页面(如图4)

图4.Leak Suspect图

Step2:进入Leak Suspects的详情页面(如图5)

图5.Leak Suspect详情页面

Step3:查看泄露可疑对象(如图6)

图6.泄露可疑对象

Step4:查看泄露可疑对象被谁引用(如图7)

图7.泄露可疑对象引用关系

Step5:可疑对象被确认为一张图片后,就查看图片的相关属性并做相应记录(如图8)

图8.查看可疑对象属性

Step6:将可疑对象保存至具体位置,便于查看图片真相,注意文件保存一定要以.data为后缀(如图9)

图9.保存图片

Step7:采用GIMP软件打开刚保存的文件,修改图片类型以及宽和高(宽高和Step5中属性一致)(如图10)

图10.GIMP打开图片

至此我们就可以确定该可疑对象是哪张图片,然后找到相应的代码,查看为何该图片没有释放,为何它这么大,是否可以优化?

方法1优化建议:

1.如果是切图问题或是矢量图,可以从图片上进行优化,如制作成.9图抑或自己用xml做drawable图;

2.如果使用完没有释放,抑或还没有显示就已经加载,可以考虑采用ViewStub来加载,但ViewStub不能与merge共同使用,否则会报错。

方法2:利用Top Consumers或Dominator Tree查看大对象(如图11-12)

图11. 利用Top Consumers查看大对象

图12 利用Dominator Tree查看大对象

由于此种方法比较直观,在此就不赘述,如有不懂请自行查阅其他文献

方法2优化建议:

当面对大对象时,如果是集合类存储的对象,可以考虑使用下Android提供的ArrayMap以及SparseArray来替换HashMap;

方法3:利用Histogram和Dominator Tree分析内存泄露

在分析内存泄露时,必须要掌握粒度,所谓粒度就是你此刻dump的hprof文件究竟是分析谁的泄露,如果你在开始前心中没有个目标,最后取出来的hprof也分析不出什么原因。粒度越小,对你分析问题也就越有利,当你把一个个小粒度问题解决后,整个App的泄露就迎刃而解了。也许这么说,大家心中有点迷糊。下面就举例来说吧:

假如现在有个项目包含Module几十个,每个Module包含的Activity数以百计,现在让你分析它是否内存泄露,如果你只是胡乱抓个hprof根本分析不出什么。假如你就针对某个Activity分析这样问题就简单多了。比如你现在分析ActivityA的内存泄露问题,你可以参考如下步骤:

Step1:进入ActivityA之前,你先dump个hprof文件HprofA;

Step2:进入ActivityA操作一会,再退出ActivityA后dump个hprof文件HprofB;

Step3:采用Histogram和Dominator Tree对比分析这两个Hprof文件,即可得出ActivityA是否泄露

现在以分析TestActivity为例,按上述步骤实战分析,先抓取进入TestActivity前后的hprof文件,按如下步骤对比两个hprof的异同(如图13-14):

图13 选择所需比较的hprof

图14 比较两个hprof

正如图14所示,易知在执行进出TestActivity后,多出了个TestActivity对象,按理论上来说在进入Activity后会创建个Activity,但是按Back键返回后这个Activity就会被销毁进而从Task栈上被移除,也就是说这个操作前后不应该会多出个Activity,因此可以断定TestActivity存在泄漏。

TestActivity存在泄漏,那我们应该怎么解决呢?因此我们就需要找到为何泄漏,为什么本该销毁的Activity却没有被销毁?如知真相如何,请看下图15-16

图15 获取TestActivity的Reference chain

图16TestActivity的引用关系

从图16易知TestActivity没有被释放就是因为GC Root(TestActivity$1)引用着TestActivity,到此原因也一目了然。找到了只是开始,解决才是关键。这时让我们查看下TestActivity代码:

public class TestActivity extends Activity {   private static final Object mLock = new Object(); @Overrideprotected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);DebugUtil.StrictModeDebug();setContentView(R.layout.test_main);   new Thread(){//匿名线程public void run() {synchronized (mLock) {try {mLock.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}.start();}
}

从代码上可以发现TestActivity里存在个匿名线程,且一直处于等待状态,直到退出TestActivity仍未被唤醒,进而导致该线程就一直没有结束,它所持有的TestActivity也就无法被释放了(可能大家听到此处会很疑惑,线程没有结束可以理解,但是它并没有持有TestActivity呀?我只能说是隐含this,如还不明白,请自行参阅java内部类相关内容),如要解决此泄露,只需在Activity的onDestory里将线程唤醒让其可以正常结束就OK了。

方法3优化建议:

1.使用线程时,一定要确保线程在周期性对象(如Activity)销毁时能正常结束,如能正常结束,但是Activity销毁后还需执行一段时间,也可能造成泄露,此时可采用WeakReference方法来解决,另外在使用Handler的时候,如存在Delay操作,也可以采用WeakReference;

2.使用Handler + HandlerThread时,记住在周期性对象销毁时调用looper.quit()方法;

3.建议少使用匿名类或内部类,可考虑使用嵌套类(带static那种类),减少对周期性对象的隐性持有;

至此,MAT使用也告一段落,但其功能远不止于此,如需了解更多可参阅如下网址:

1.http://ju.outofmemory.cn/entry/129445

2.http://developer.android.com/intl/zh-cn/training/improving-layouts/smooth-scrolling.html#ViewHolder

3.http://help.eclipse.org/luna/index.jsp?topic=/org.eclipse.mat.ui.help/welcome.html

内存泄露分析之MAT工具使用相关推荐

  1. 如何使用MAT进行JVM内存泄露分析

    转载自  如何使用MAT进行JVM内存泄露分析 在<Java Agent的隔离实现以及卸载时一些坑>中,卸载Agent之后,使用 jmap-histo:live pid命令验证执行FGC, ...

  2. JAVA内存泄露分析和解决方案及WINDOWS自带查看工具

    JAVA内存泄露分析和解决方案及WINDOWS自带查看工具 Java内存泄漏是每个Java程序员都会遇到的问题,程序在本地运行一切正常,可是布署到远端就会出现内存无限制的增长,最后系统瘫痪,那么如何最 ...

  3. java内存泄露分析方案

    java内存泄露分析方案 - 准备工作 1.工具:Memory Analyzer Tool (mat); 1)安装Memory Analyzer Tool (mat) 2.原料:dump.hprof ...

  4. 记一次 JAVA 的内存泄露分析

    记一次 JAVA 的内存泄露分析 摘要:本文属于原创,欢迎转载,转载请保留出处:https://github.com/jasonGeng88/blog 当前环境 jdk == 1.8 httpasyn ...

  5. 一次.net托管内存泄露分析

    简介:一次.net托管内存泄露分析 最近协助分析了一个.net进程内存泄露的问题,过程分享给大家. 症状:客户的服务端.net进程出现分钟级的cpu抖动,接近100%后落回. 图1 分析:支持同学通过 ...

  6. Android studio内存泄露分析工具

    使用 Android Studio 检测内存泄漏与解决内存泄漏问题 本文在腾讯技术推文上 修改 发布. http://wetest.qq.com/lab/view/63.html?from=ads_t ...

  7. linux 进程内存分析工具,Linux内存使用情况以及内存泄露分析之工具与方法

    1. 内存使用情况分析 1.1 系统总内存分析 通过cat /proc/meminfo,可用的物理内存=MemFree+Buffers+Cached. MemTotal:        5933132 ...

  8. 利用MAT进行内存泄露分析

    前言 对于程序员来说码代码容易,保证代码的稳定性很难.有时候写完一个功能可能只需要一天时间,但是这个功能隐藏的bug导致的线上问题排查可能需要一周或者更长时间.因此,拥有良好的代码结构和编码规范是一个 ...

  9. linux 内存泄露 工具,Linux Kernel模块内存泄露分析

    1.通过free 看 剩余内存 # free total used free shared buffers Mem: 2065866752 1268113408 797753344 0 9060352 ...

最新文章

  1. 依赖注入?依赖注入是如何实现解耦的?
  2. 东软信息学院java试题,东软Java笔试题答案
  3. 【实战演练】两种方法让 Docker 帮您快速构建应用程序
  4. 2.Java异常学习
  5. [zz]volatile
  6. java web 的粗粒度权限管理
  7. google js cdn_「效率工具」模拟CDN的浏览器扩展程序,改善在线隐私
  8. asp服务器_Asp.Net Core2.2从环境配置到应用建立
  9. Beam概念学习系列之SDKs
  10. 微软私有云解决方案_毕马威 AI 工厂携手微软云技术 | 共创人工智能发展,共建创新解决方案...
  11. 框架笔记:记录XLua的简单接入
  12. WPF特效-粒子动画
  13. 苹果WWDC 2019看点回顾:iOS黑化、iPad系统独立、王者Mac Pro发布...
  14. 计算机智能测试与机电工程学,机电工程学院智能技术创新团队论文被国际计算机视觉顶级会议ICCV录用...
  15. java textfield事件_java – 以编程方式触发JTextField中的键事件...
  16. Atitit.404错误解决标准流程and url汉字中文路径404错误resin4 resin chinese char path 404 err解决
  17. 计算机Word2010中刷新键,Office2010常用快捷键汇总(最新整理)
  18. 卡尔曼滤波算法-Matlab仿真
  19. 手游渠道出现三大变量
  20. ICPC2017沈阳赛区游记

热门文章

  1. Nuance“背叛”苹果:应用语音助理Nina能对抗Siri吗?
  2. 嵌入式系统下Microwindows的实现
  3. 易基因文献速递|BS-miRNA-seq技术发现人类microRNA中CpG和 非CpG上的(h)m5C修饰
  4. PL/SQL 基础知识
  5. WV.21-大数阶乘算法1-序
  6. 2018最新版省市区三级联动下拉框+所有源代码以及数据库
  7. Putty的噩梦——渗透工具PuttyRider使用心得分享
  8. ARM Linux Data Abort 异常处理流程
  9. Notepad-- Windows版本安装、简单体验
  10. 【老生谈算法】matlab实现Kmeans聚类算法源码——Kmeans聚类算法