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等窗口机制进行解析。
网友评论