美文网首页内存优化
Android内存泄漏之非静态内部类

Android内存泄漏之非静态内部类

作者: 烬日沉香 | 来源:发表于2018-07-28 14:00 被阅读250次

    原因

    页面退出时,post到handler的runnable是延迟任务,还未到时延,且作为非静态内部匿名类,持有了外部TvTaobaoImp的强引用,而TvTaobaoImp持有着Activity的context,导致Activity没有被回收。

    分析

    可以用LeakCannry检测是否存在内存泄漏,如果存在,会出警告,并给出提示信息。作者君这里直接分析了dump下来的堆转储文件。
    TvTaoBaoImp对象持有callBack,这是个runnable,非静态内部类,支持TvTaoBaoImp,它被post到MessageQuene队列中,Looper会循环去取里头的Message处理,页面退出时,该Message尚未被处理。于是一级级被持有,最终导致Activity也无法被释放。


    image.png image.png

    找到泄露的地方,解决方案就非常简单了:
    1.handler作为内部静态类,以软引用的方式持有外部对象。
    2.由于逻辑上本身在页面退出后不需要再执行延时里的业务代码,因此在页面退出后,清空handler的message和runnable。

    小结

    使用延迟消息需要谨慎,注意页面退出是否该消息还需要执行,若需要可以使用软引用,若不需要则将消息从队列中移除。
    有时候泄漏的本质,就是彼此生命周期不一样了,一方结束,另一方还未结束,不能一上来都用弱引用,引用类型各有其存在的合理性,各有优缺点。作者君的业务场景,实则是二者的生命周期不一致,页面消失时,runnable也不应该再执行。

    相关文章

      网友评论

        本文标题:Android内存泄漏之非静态内部类

        本文链接:https://www.haomeiwen.com/subject/qtjomftx.html