当前位置:操作系统 > 安卓/Android >>

android-内存溢出-子view未回收-非大众版

1、Mat内存分析工具的安装和使用:
 
-------------------------安装-------------------------
 
准备环境和测试数据
 
我们使用的是 Eclipse Memory Analyzer V0.8,Sun JDK 6
 
安装 MAT
 
和其他插件的安装非常类似,MAT 支持两种安装方式,一种是“单机版“的,也就是说用户不必安装 Eclipse IDE 环境,MAT 作为一个独立的 Eclipse RCP 应用运行;另一种是”集成版“的,也就是说 MAT 也可以作为 Eclipse IDE 的一部分,和现有的开发平台集成。
 
集成版的安装需要借助 Update Manager。
 
如图 1 所示,首先通过 Help -> Software Updates... 启动软件更新管理向导。
 
图 1. 安装插件第一步
图 1. 安装插件第一步
 
选择“Available Software“然后按如图 2 所示的方式添加 MAT 的更新地址 http://download.eclipse.org/technology/mat/0.8/update-site/。
 
 
图 2. 安装插件第二步
图 2. 安装插件第二步
如图 3 所示,接下来选择你想要安装的 MAT 的功能点,需要注意的是 Memory Analyzer (Chart) 这个功能是一个可选的安装项目,它主要用来生成相关的报表,不过如果需要用到这个功能,你还需要额外的安装 BIRT Chart Engine。
 
 
图 3. 安装插件第三步
图 3. 安装插件第三步
插件安装完毕,你还需要重新启动 Eclipse 的工作平台。
 
 
 
 
 
-------------------------使用-------------------------
 
for mat plugin version, is u want to use it:
 
  2.1:  open mat view pespective.
 
    
 
 
2.2   get a img of heap in android dev , u can goto ddms view, and press  button. the save the img file . (需要选择对应的应用程序。)
     
 
2.3  open the imgfile. (一般经过了2.2的一步,会自动打开2.4步骤的东西)
 
      u must in mat model   
      
 
    then  u can ..
 
      
 
  2.4  打开
 
   
 
    
 
 
 
2、Mat分析内存溢出的问题
 
分析三步曲
 
通常我们都会采用下面的“三步曲”来分析内存泄露问题:
 
首先  ,对问题发生时刻的系统内存状态获取一个整体印象。
 
第二步,找到最有可能导致内存泄露的元凶,通常也就是消耗内存最多的对象
 
接下来,进一步去查看这个内存消耗大户的具体情况,看看是否有什么异常的行为。
 
下面将用一个基本的例子来展示如何采用“三步曲”来查看生产的分析报告。
 
查看报告之一:内存消耗的整体状况
 
 
图 7. 内存泄露分析报告
图 7. 内存泄露分析报告
如图 7 所示,在报告上最醒目的就是一张简洁明了的饼图,从图上我们可以清晰地看到一个可疑对象消耗了系统 99% 的内存。
 
在图的下方还有对这个可疑对象的进一步描述。我们可以看到内存是由 java.util.Vector 的实例消耗的,com.ibm.oti.vm.BootstrapClassLoader 负责这个对象的加载。这段描述非常短,但我相信您已经可以从中找到很多线索了,比如是哪个类占用了绝大多数的内存,它属于哪个组件等等。
 
接下来,我们应该进一步去分析问题,为什么一个 Vector 会占据了系统 99% 的内存,谁阻止了垃圾回收机制对它的回收。
 
查看报告之二:分析问题的所在
 
首先我们简单回顾下 JAVA 的内存回收机制,内存空间中垃圾回收的工作由垃圾回收器 (Garbage Collector,GC) 完成的,它的核心思想是:对虚拟机可用内存空间,即堆空间中的对象进行识别,如果对象正在被引用,那么称其为存活对象,反之,如果对象不再被引用,则为垃圾对象,可以回收其占据的空间,用于再分配。
 
在垃圾回收机制中有一组元素被称为根元素集合,它们是一组被虚拟机直接引用的对象,比如,正在运行的线程对象,系统调用栈里面的对象以及被 system class loader 所加载的那些对象。堆空间中的每个对象都是由一个根元素为起点被层层调用的。因此,一个对象还被某一个存活的根元素所引用,就会被认为是存活对象,不能被回收,进行内存释放。因此,我们可以通过分析一个对象到根元素的引用路径来分析为什么该对象不能被顺利回收。如果说一个对象已经不被任何程序逻辑所需要但是还存在被根元素引用的情况,我们可以说这里存在内存泄露。
 
现在,让我们开始真正的寻找内存泄露之旅,点击“Details ”链接,可以看到如图 8 所示对可疑对象 1 的详细分析报告。
图 8. 可疑对象 1 的详细分析报告
 
图 8. 可疑对象 1 的详细分析报告
 
我们查看下从 GC 根元素到内存消耗聚集点的最短路径:
 
图 9. 从根元素到内存消耗聚集点的最短路径
vcTatObP+7rEvtu8r7XjtcTX7rbMwre+tg==" src="/2013/0108/20130108084732397.jpg" />
我们可以很清楚的看到整个引用链,内存聚集点是一个拥有大量对象的集合,如果你对代码比较熟悉的话,相信这些信息应该能给你提供一些找到内存泄露的思路了。
 
接下来,我们再继续看看,这个对象集合里到底存放了什么,为什么会消耗掉如此多的内存。
 
 
图 10. 内存消耗聚集对象信息
图 10. 内存消耗聚集对象信息
在这张图上,我们可以清楚的看到,这个对象集合中保存了大量 Person 对象的引用,就是它导致的内存泄露。
 
至此,我们已经拥有了足够的信息去寻找泄露点,回到代码,我们发现,是下面的代码导致了内存泄露 :
 
 
清单 1. 内存泄漏的代码段
 
 while (1<2) 
 { 
 
Person person = new Person("name","address",i); 
v.add(person); 
person = null; 
 } 
 
 
 
总结
 
 
从上面的例子我们可以看到用 MAT 来进行堆转储文件分析,寻找内存泄露非常简单,尤其是对于新手而言,这是一个很好的辅助分析工具。但是,MAT 绝对不仅仅是一个“傻瓜式”内存分析工具,它还提供很多高级功能,比如 MAT 支持用 OQL(Object Query Language)对 heap dump 中的对象进行查询,支持对线程的分析等,有关这些功能的使用可以参考 MAT 的帮助文档。
 
 
补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,