Handler内存泄漏简析实践

被刻印的时光 ゝ 提交于 2020-02-06 16:50:14

1.反编译工具javap

javap -help

javap class // 查看类变量与方法

javap -c //查看反汇编代码

javap -v //查看附加信息

2.window不识别java命令

path // jdk 绝对路径\bin; jre绝对路径\bin

C:\Program Files\Java\jdk7\bin;C:\Program Files\Java\jre7\bin

java_home //jdk path

classpath //;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar

3.外部类和内部类

public class Outer {
    public class Inner {
    }
}
javac Outer.java 编译生成两个字解码文件Outer$Inner.class和Outer.class
javap -v Outer$Inner.class
Outer$Inner.class存在一个成员变量Outer this$0,这个就是外部类的实例.
修改Inner为静态类,发现Outer$Inner.class,没有外部类的实例。这说明非静态内部类实际上会持有外部类对象的引用。

4.Handler内存泄漏场景解析

public class MainActivity extends AppCompatActivity {
    ... ...
    Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };
}
Handler是非静态内部类,持有外部MainActivity类的引用
如果在Handler发送如下的延迟消息,
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
              // do some thing
            }
        }, 1000 * 60 * 30);
这个Handler将一直持有外部类的引用,直到30分钟之后才能够释放,导致外部的MainActivity对象无法被销毁。
如果在短时间内重复打开应用、然后按Back键退出几十次以后,内存中MainActivty的对象存在多个,通过android studio或者ddms可以查看堆栈情况

4.1Handler内存分析方法

Android Studio 3.0 采用全新的 Android Profiler 窗口取代 Android Monitor 工具。 这些全新的分析工具能够提供关于应用 CPU、内存和网络 Activity 的实时数据。

Allocated 您的应用分配的 Java/Kotlin 对象数。此数字没有计入 C 或 C++ 中分配的对象。:从 Java 或 Kotlin 代码分配的对象的内存

5.常见的解决方案

构建静态内部类

 

参考

http://huzhengyu.com/2019/09/29/handler-leak/

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!