一般android里的内存泄漏都是activity泄漏,测试方法通常是在back回到桌面的时候,查看其activity,view实例对象是否为0来判断,activity泄漏一般比较好定位,方法网上文章也有很多,都是通过查看acitivity对象的gcroot路径来看是谁引用了来定位问题。
最近在开发过程中遇到activity实例为0但是view/viewroot实例不为0的情况,这种情况定位问题跟前面的情况稍微有所不同,需要有更多的信息来定位问题。遇到这种情况时,需要查看ViewRoot的gcroot路径来定位,了解android的都知道,ViewRoot的实现类为ViewRootImpl,可以查看这个类的实例的gcroot路径是怎样的,来看实例:

class android.view.WindowManagerGlobal @ 0x71112f90    sDefaultWindowManager android.view.WindowManagerGlobal @ 0x12d4a8d8        mRoots java.util.ArrayList @ 0x13027908            elementData java.lang.Object[10] @ 0x13027970                [0] android.view.ViewRootImpl @ 0x13023058

乍一看,这里面对我们没有有用的信息,因为这里没有任何跟我们代码相关的东西,这时就需要我们仔细分析一下了,因为这是ViewRoot泄漏,而ViewRoot是activity最顶层view相关的操作类,注意他不是一个真实的view,它只是用来做绘制相关的事情,真实的顶层view是叫DecorView,DecorView是window下的成员变量,每个Activity都有个Window,从这里的分析可以试下看DecorView对象是不是还存在,可是很遗憾,搜索了DecorView对象,发现实例为0。这说明Activity相关的View应该已经都被销毁了,但为什么View和ViewRoot还存在呢,难道不是Activity里面的view?这时有个关键的线索是ViewRootImpl里有个mView对象,它是加到WindowManager时的布局对象,通过查看这个mView对象可以看一下布局到底是怎样的。于是查看ViewRootImpl的with outcoming refrence并查看mView对象:

mView android.widget.LinearLayout @ 0x13023810    

可以看到mView是一个LinearLayout,它的mChildren里有一个TextView,TextView的value是“请输入正确格式”,用这个文本去代码搜索里,终于找到,原来是弹的Toast。至此,我们终于找到原因:
原来是Toast引发了内存泄漏,因为Toast并不用依附在Activity,所以我们看到acitvity实例为0,DecorView实例也为0,这又是个android框架里的内存泄漏!另外我们在查找内存泄漏问题时可以多查看对象的成员变量信息,看一下有没有跟我们代码里可以关联起来的,这是比较重要的思路!

更多相关文章

  1. [置顶] android面试大宝典
  2. Android(安卓)Activity生命周期和堆栈管理的详解
  3. Android(安卓)CPU Memory 资源测试和分析 (使用工具 0xbench + p
  4. Android系统设计中的设计模式分析之一
  5. Handler异步方式详解及其使用 .(转)
  6. 关于ANDROID task运行机制
  7. Android实现记事本小功能
  8. Android(安卓)设计模式 之 单例模式
  9. Android基础入门教程——3.3 Handler消息传递机制浅析

随机推荐

  1. Android进程与线程基本知识
  2. android的测试工具CTS
  3. android的测试工具CTS
  4. 从Android读取Unity assets下的图片并保
  5. Android(安卓)核心分析 之七------Servic
  6. Android获取存储设备挂载路径
  7. Android(安卓)AsyncTask
  8. Android里的shell的系统命令
  9. unity-与Android交互(unity5、android st
  10. Ubuntu Touch 只是另一个 Android(安卓)