内存泄漏
Android 的虚拟机是基于寄存器的 Dalvik,它的最大堆大小一般是
16M,有的机器为
24M。因此我们所能利用
的内存空间是有限的。如果我们的内存占用超过了一定的水平就会出现 OutOfMemory
的错误。
什么情况会导致内存泄漏
1.资源释放问题
长期保持某些资源,比如Context,Cursor,IO流的引用,资源得不到释放造成内存泄漏
2.对象内存过大问题
保存了多个耗用内存过大的对象(如 Bitmap、XML
文件),造成内存超出限制。
3.static 关键字的使用问题
static是Java中的一个关键字,当用他来修饰成员变量时,那么该变量就属于该类,而不是该类的实例
所以用static修饰的变量,生命周期是很长的
如果用他来引用一些资源耗费过多的实例(Context的情况最多), 就要谨慎对待了
打个比方
public class ClassName{
private static Context mContext;
}
这样的代码是非常危险的
如果把Activity赋值到mContext的话,
就算这个Activity已经onDestroy了,
但是由于仍然有对象保存他的引用,那么这个Activity还是不会被释放
再举个Android官方文档中的栗子
private static Drawable sBackground;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this); //getApplicationContext
label.setText("Leaks are bad");
if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
我们来看这段代码
先是有一个静态的Drawable sBackground
然后是onCreate方法
然后new了一个TextView,设置了一下Text(...)
然后是判断,如果为sBackground为null
那么sBackground=getDrawable(R.drawable.large_bitmap);
注意了:
这里虽然没有显式的保存Context的引用,
但是,当Drawable与View连接了之后,Drawable就将View设置为一个回调
由于View中是包含了Context的引用的,
所以实际上还是保存了Context的引用
引用链: Drawable--TextView--Context
所以,Context还是没有被释放,发生了内存泄漏
针对static的解决方案
1.尽量避免static成员变量引用资源耗费过多的实例,比如Context
2.Context尽量使用ApplicationContext,因为Application的Context的生命周期很长,
引用它不会出现内存泄漏的问题
3.使用WeakReference代替强引用,比如可以使用
WeakReference<Context> mContextReference;