Android View/ViewRoot泄漏但Activity不泄漏问题

一般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
    <class, shadow$_kclass class android.widget.LinearLayout @ 0x7111da20
    mContext com.xxx.calculator.CalculatorApplication @ 0x12d4b088
    mResources android.content.res.Resources @ 0x12f79468
    mParent android.view.ViewRootImpl @ 0x13023058
    mAttachInfo android.view.View$AttachInfo @ 0x13023270
    mChildren android.view.View[12] @ 0x13023c68
        <class, shadow$_kclass class android.view.View[] @ 0x12d655c8
        [0] android.widget.TextView @ 0x13024070
            <class, shadow$_kclass class android.widget.TextView @ 0x7111a018
            mContext com.xxx.calculator.CalculatorApplication @ 0x12d4b088
            mResources android.content.res.Resources @ 0x12f79468
            mText, mTransformed java.lang.String 请输入正确格式
            <class, shadow$_kclass class java.lang.String @ 0x70d96660
            value char[7] 请输入正确格式

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值