【Android】Eclipse Memory Analyzer 进行堆内存溢出分析

    MAT 不是一个万能工具,它并不能处理全部类型的堆存储文件。java

     不一样厂家的 JVM 所生成的堆转储文件在数据存储格式以及数据存储内容上有不少区别, 可是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析。
    另外, 有不少的工具,例如 JMap,JConsole 均可以帮助咱们获得一个堆转储文件。

1.一键式的堆存储分析功能

     生成分析报告

首先,启动安装配置好的 Memory Analyzer tool , 而后选择菜单项 File- Open Heap Dump(eclipse会自动载入)来加载须要分析的堆转储文件。android

文件加载完成后,你能够看到以下图所示的界面浏览器

经过上面的概览,咱们对内存占用状况有了一个整体的了解。多线程

另外,MAT 工具提供了一个很贴心的功能,将报告的内容压缩打包到一个 zip 文件,并把它存放到原始堆转储文件的存放目录下,这样若是您须要和同事一块儿分析这个内存问题的话,只须要把这个小小的 zip 包发给他就能够了,不须要把整个堆文件发给他。而且整个报告是一个 HTML 格式的文件,用浏览器就能够轻松打开。eclipse

接下来咱们就能够来看看生成的报告都包括什么内容,能不能帮咱们找到问题所在吧。您能够点击工具栏上的 Leak Suspects 菜单项来生成内存泄露分析报告,也能够直接点击饼图下方的 Reports->Leak Suspects 连接来生成报告。工具

2.分析三步曲

一般咱们都会采用下面的“三步曲”来分析内存泄露问题:优化

  1. 首先,对问题发生时刻的系统内存状态获取一个总体印象。
  2. 第二步,找到最有可能致使内存泄露的元凶,一般也就是消耗内存最多的对象
  3. 接下来,进一步去查看这个内存消耗大户的具体状况,看看是否有什么异常的行为。

下面将用一个基本的例子来展现如何采用“三步曲”来查看生产的分析报告。spa

2.1 查看报告之一:内存消耗的总体情况

  内存泄露分析报告,以下图所示
  
 
 
  如上图所示,在报告上最醒目的就是一张简洁明了的饼图,从图上咱们能够清晰地看到一个可疑对象消耗了系统 70% 的内存。
  
  在图的下方还有对这个可疑对象的进一步描述。咱们能够看到内存是由 android.content.res.Resources 的实例消耗的,system class loader 负责这个对象的加载。这段描述很是短,但已经能够从中找到不少线索了,好比是哪一个类占用了绝大多数的内存,它属于哪一个组件等等。
  接下来,咱们应该进一步去分析问题,为何一个Resources会占据了系统 70% 的内存,谁阻止了垃圾回收机制对它的回收。

2.2 查看报告之一:分析问题的所在

  首先简单回顾下 JAVA 的内存回收机制,内存空间中垃圾回收的工做由垃圾回收器 (Garbage Collector,GC) 完成的,它的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,若是对象正在被引用,那么称其为存活对象,反之,若是对象再也不被引用,则为垃圾对象,能够回收其占据的空间,用于再分配。
在垃圾回收机制中有一组元素被称为根元素集合,它们是一组被虚拟机直接引用的对象,好比,正在运行的线程对象,系统调用栈里面的对象以及被 system class loader 所加载的那些对象。堆空间中的每一个对象都是由一个根元素为起点被层层调用的。
  所以,一个对象还被某一个存活的根元素所引用,就会被认为是存活对象,不能被回收,进行内存释放。所以,咱们能够经过分析一个对象到根元素的引用路径来分析为何该对象不能被顺利回收。若是说一个对象已经不被任何程序逻辑所须要可是还存在被根元素引用的状况,咱们能够说这里存在内存泄露。

如今,让咱们开始真正的寻找内存泄露之旅,点击“Details ”连接,能够看到以下图所示对可疑对象的详细分析报告。线程

  
  咱们查看下从 GC 根元素到内存消耗汇集点的最短路径:
  

咱们能够很清楚的看到整个引用链,内存汇集点是一个拥有大量对象的集合,若是你对代码比较熟悉的话,相信这些信息应该能给你提供一些找到内存泄露的思路了。对象

接下来,咱们再继续看看,这个对象集合里到底存放了什么,为何会消耗掉如此多的内存。

在这张图上,咱们能够清楚的看到,这个对象集合中保存了大量图片对象的引用,可能就是它致使的内存泄露等问题。

再仔细看......

 

实际上这些位图真正占用的内存只有一丁点,可是java虚拟机为其保留了70%的内存备用,这些内存没有被回收,因此利用率几乎为 0 !

今后处你们均可以知道了,应用里面图片多了实际上是一件悲剧的事,至少可能会给应用带来许多不可预知的问题,并且在图片方面的内存优化是比较麻烦的,哎,最近搞内存泄露,涉及到动态库,JNI,多线程,资源同步与竞争等,蛋疼的事 ......

 

有些图片为Android预加载部分的,具体可参看下面网址:http://stackoverflow.com/questions/9653457/locating-and-remedying-cause-of-large-heap-size

 


   @成鹏致远

  (blogs:lcw.cnblogs.com

  (emailwwwlllll@126.com)

  (qq552158509)

相关文章
相关标签/搜索