内存泄漏一种状况是一块内存没有引用指向它,却没被回收,这种状况已经由Java虚拟机的 GC缓存
帮助咱们处理好了,见 【拒绝一问就懵】之你多少要懂点内存回收机制;另外一种属于 逻辑内存泄漏,即一个对象已经再也不被使用了,但它仍然被另外一个被使用中的对象所持有,致使该对象所占用的内存块不能被回收。bash
少部分内存泄漏看不出有什么影响,但若是大量发生,将会明显减小可用内存,致使频繁GC,运行缓慢,严重时将容易引起OutOfMemoryError
。app
一些对象缓存到集合中,当它不在被使用时,没有从集合中移除,就形成了泄漏。异步
一个Activity中的Context一般会被不少地方引用,若是在Activity执行了onDestory()
后这些引用没有被置空,将会致使Activity没法被回收。而Activity中依赖了很对对象,这些对象将都不能被回收,因此必定要十分当心Activity的泄漏。如下几种常见的状况须要注意:ide
onDestory()
后仍然可到达,那么它持有的Activity就没法被回收。onDestory()
后,若Handler中仍然有消息在MessageQueue中,那么该Handler就不能被释放,也就意味着Activity也不会被释放。解决方法:
onDestory()
完成前确保Handler没有执行yan shi延时任务,没有被其余地方引用。同时清理Handler中全部任务,调用removeCallbacksAndMessages(null);
,该方法参数为空时会移除因此的CallBack和Message。static class MyHandler extends Handler {
private final WeakReference<Activity> mActivity;
public MyHandler(Activity activity) {
mActivity = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
System.out.println(msg);
if (mActivity.get() == null) {
return;
}
mActivity.get().todo();
}
}
复制代码
Bitmap是引用中占用内存的大户,在使用时必定要十分注意。当Bitmap不用时,应该及时调用recycle()
释放其申请的内存。post
异步任务若是在它应该中止的时候没有中止,那它自己及它所依赖的对象将都不能被正确的释放。好比上面提到的Activity中的异步任务。ui
好比在Activity中这样来开启一个异步任务:spa
new Thread(()->{
// doSomething with long-time
}).start();
复制代码
那么,在Activity已经finish()了,但异步任务中的Runnable还被持有,而且因为是属于Activity的匿名内部类,因此会致使Activity的内存不能及时回收。线程
因为系统内存资源有限,因此咱们须要尽可能避免 内存泄漏,以保证程序可以流畅运行。code