1.查询数据库而没有关闭Cursor
Cursor c =querryCursor();
try{
….
}catch(Exception e){
….
}finally{
c.close();
}
这样写能保证在发生异常时也可以正常关闭cursor
2.InputStream 、OutputStream 未关闭导致的内存泄露
3.广播BroadCastReceiver注册后未调用unregisterReceiver
4.Bitmap使用后未recycle
5.Context内存泄露
5.1static Drawable 引起的context泄露
这种情况发生在Android 3.0之前,查看setBackgroundDrawable(Drawable background)方法源码里面有一行代码引起我们的注意:
public void setBackgroundDrawable(Drawable background) {
// ... ...
background.setCallback(this);
// .... ....
}
这里this持有对view的引用,而view持有对当前activity的引用。所以当activity退出时,由于 static Drawable 是静态变量,它的生命周期没有结束,而它间接持有activity的引用,导致当前activity无法被销毁引起内存泄露。
Android 3.0 后 官方对setCallback()做了如下调整,从而有效的避免了这一内存泄露
public final void setCallback(Callback cb) {
mCallback = new WeakReference<Callback>(cb);
}
5.2 System Service 引起的内存泄露
一些厂商定义的服务,或者厂商自己修改了一些新的代码导致系统服务引用了Context对象不能及时释放,我曾经碰到过Wifi,Storage服务都有内存泄露。这时候我们传application 就可以得到解决。
5.3 Handler 引起的内存泄露
handler内存泄露的两个因素
1)内部类
2)生命周期与activity 不一致
解决方案:
1)静态内部类+弱引用
静态内部类不会持有对外部类的引用
2)在Activity onStop或者onDestroy的时候,取消掉该Handler对象的Message和Runnable, removeCallbacks(Runnable r)和removeMessages(int what)等。
5.4 Thread 引起的内存泄露
同Handler对象可能造成内存泄露的原理一样,Thread的生命周期不一定是和Activity生命周期一致。
而且因为Thread主要面向多任务,往往会造成大量的Thread实例。
据此,Thread对象有2个需要注意的泄漏点:
1). 创建过多的Thread对象
2). Thread对象在Activity退出后依然在后台执行
解决方案是:
1). 使用ThreadPoolExecutor,在同时做很多异步事件的时候是很常用的,这个不细说。
2). 当Activity退出的时候,退出Thread。