內存泄漏一種狀況是一塊內存沒有引用指向它,卻沒被回收,這種狀況已經由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