1.GC root:java
一、 Class:由系統的類加載器加載的類對象android 二、 Static Fields網絡 三、 Thread:活着的線程ide 四、 Stack Local: java方法的局部變量或參數函數 五、 JNI Local: JNI方法中的局部引用工具 六、 JNI Global: 全局的JNI引用post 七、 Monitor used: 用於同步的監控對象google 八、Help by VM: 用於JVM特殊目的由GC保留的對象spa |
每一個應用最大可以使用的堆內存受到Android系統的限制:getMemoryClass()線程
2.context內存泄露
一、若是一個類持有Context對象的強引用,就須要檢查其生存週期是否比Context對象更長。不然就可能發生Context泄漏。 二、View持有其建立所在Context對象的引用,若是將View對象傳遞給其它生存週期比View所在Context更長的強引用,就可能會引發內存泄漏。 例如View#setTag(int, Object)的內存泄漏https://code.google.com/p/android/issues/detail?id=18273 三、把Context對象賦給static變量。 |
避免Context對象泄漏Checklist 一、檢查全部持有對Context對象強引用的對象的生命週期是否超出其所持有的Context對象的生命週期。 二、檢查有沒有把View傳出到View所在Context以外的地方,若是有的話就須要檢查生命週期。 三、工具類中最好不要有Context成員變量,儘可能在調用函數時直接經過調用參數傳入。若是必須有Context成員變量時,能夠考慮使用WeakReference來引用Context對象。 四、View持有其建立所在Context對象的引用,若是將View對象傳遞給其它生存週期比View所在Context更長的強引用,就可能會引發內存泄漏。 五、 檢查把Context或者View對象賦給static變量的地方,看是否有Context泄漏。 六、檢查全部把View放入容器類的地方(特別是static容器類),看是否有內存泄漏。七、使用WeakHashMap也須要注意有沒有value-key的引用。 七、儘可能使用ApplicationContext。 |
3.handler泄露
發送到Handler的Message其實是加入到了主線程的消息隊列等待處理,每個Message持有其目標Handler的強引用。
如咱們一般使用的匿名內部類Handler
Handler mHandler = new Handler() { @Override public voidhandleMessage(Message msg) { mImageView.setImageBitmap(mBitmap); } }
上面是一段簡單的Handler的使用。當使用內部類(包括匿名類)來建立Handler的時候,Handler對象會隱式地持有一個外部類對象(一般是一個Activity)的引用,由於View會依附着一個Activity。而Handler一般會伴隨着一個耗時的後臺線程(例如從網絡拉取圖片)一塊兒出現,這個後臺線程在任務執行完畢(例如圖片下載完畢)以後,經過消息機制通知Handler,而後Handler把圖片更新到界面。然而,若是用戶在網絡請求過程當中關閉了Activity,正常狀況下,Activity再也不被使用,它就有可能在GC檢查時被回收掉,但因爲這時線程還沒有執行完,而該線程持有Handler的引用(否則它怎麼發消息給Handler?),這個Handler又持有Activity的引用,就致使該Activity沒法被回收(即內存泄露),直到網絡請求結束(例如圖片下載完畢)。另外,若是你執行了Handler的postDelayed()方法,該方法會將你的Handler裝入一個Message,並把這條Message推到MessageQueue中,那麼在你設定的delay到達以前,會有一條MessageQueue -> Message -> Handler -> Activity的鏈,致使你的Activity被持有引用而沒法被回收。
固然,應爲是Handler對外部持有引用的緣由,咱們就能夠將Activity設置爲一個弱引用,在沒必要要的時候,再也不執行內部方法。
publicclass WeakRefHandler extends Handler { WeakReference<Context> mWeakContext; public WeakRefHandler(Context context) { mWeakContext = newWeakReference<Context>(context); } @Override public void handleMessage(Message msg) { if((mWeakContext.get() instanceofActivity )&& ((Activity)mWeakContext.get()).isFinishing()) return ; if(mWeakContext==null){ return ; } super.handleMessage(msg); } }