美文网首页
Android 内存泄漏 - 不要用static修饰控件

Android 内存泄漏 - 不要用static修饰控件

作者: chengjian666 | 来源:发表于2018-04-04 16:48 被阅读45次

    LeakCanary 工具集成

    LeakCanary是android平台用于内存泄漏检测的开源工具,使用方法十分简单,其github地址:
    LeakCanary Github

    内存泄漏总结

    Avoid using non-static inner classes in an activity if instances of the inner class could outlive the activity's lifecycle

    总结来说,当内部类持有外部类的引用且它的生命周期更长时,会引发内存泄漏。

    不要用static修饰控件

    如下代码示例:

    public class CameraViewActivity extends AppCompatActivity {
        //注意此处的static修饰符
        private static ImageView imageView;
         @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    }
    

    对于ImageView的控件,如果设置为static会有什么影响?
    当我们使用static修饰ImageView控件时,AS会提示:

    Do not place android context classes in static fields, this is a memory leak.

    原因:
    首先被static修饰变量的生命周期,静态变量在类文件编译成字节码后,载入方法区时,就会初始化静态变量,并且静态变量会伴随整个进程(在android中即该应用的进程)一直存在。然而对于其所在的非static Activity,会在创建时在堆中申请内存,当该activity退出时,GC会依据GC_ROOT的规则遍历回收那些没有被任何地方引用的对象,但是由于该activity的context传入了静态成员ImageView中:

    ImageView view = LayoutInflater.from(context).inflate(R.layout.test,null);
    

    该ImageView的生命周期等同于整个应用,那么该activity的引用(conext)一直被持有,那么自然就始终无法被GC回收,造成内存泄漏,直到整个进程终止(体现为android application crash)。

    关于ImageView是如何持有context,则需要针对PhoneWindow等窗口机制进行解析。

    相关文章

      网友评论

          本文标题:Android 内存泄漏 - 不要用static修饰控件

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