概念根搜索算法Android虛擬機的垃圾回收采用的是 根搜索算法相比引用計數(shù)法很好的解決了循環(huán)引用的問題。舉個例子,Activity有View的引用,View也有Activity的引用,之前我還嘗試去源代碼里找Activity何時和View斷開連接是大錯特錯了。當Activity finish掉之后,Activity和View的循環(huán)引用已成孤島,不再引用到GC Roots,無需斷開也會被回收掉。 內(nèi)存泄漏
場景
靜態(tài)變量長期維持到大數(shù)據(jù)對象的引用,阻止垃圾回收。 非靜態(tài)內(nèi)部類會維持一個到外部類實例的引用,如果非靜態(tài)內(nèi)部類的實例是靜態(tài)的,就會間接長期維持著外部類的引用,阻止被回收掉。 資源性對象如Cursor、File、Socket,應(yīng)該在使用后及時關(guān)閉。未在finally中關(guān)閉,會導(dǎo)致異常情況下資源對象未被釋放的隱患。 未反注冊會導(dǎo)致觀察者列表里維持著對象的引用,阻止垃圾回收。 Handler臨時性內(nèi)存泄露Handler通過發(fā)送Message與主線程交互,Message發(fā)出之后是存儲在MessageQueue中的,有些Message也不是馬上就被處理的。在Message中存在一個 target,是Handler的一個引用,如果Message在Queue中存在的時間越長,就會導(dǎo)致Handler無法被回收。如果Handler是非靜態(tài)的,則會導(dǎo)致Activity或者Service不會被回收。 由于AsyncTask內(nèi)部也是Handler機制,同樣存在內(nèi)存泄漏的風險。 此種內(nèi)存泄露,一般是臨時性的。 預(yù)防
context-application代替context-activityWeakReference代替。檢測靜態(tài)檢測靜態(tài)檢測主要是檢測資源未關(guān)閉的情況,Eclipse和Android Studio都可以檢測出IO或者Socket未關(guān)閉的情況,然后在finally中關(guān)閉即可。 動態(tài)監(jiān)測動態(tài)檢測主要是依靠MAT這個工具。2011年Google IO有一個主題演講,非常詳細地講解了內(nèi)存泄露的檢測,包含MAT工具的使用,值得一看。 Histogram ![]() 此處輸入圖片的描述 很明顯,靜態(tài)變量 instance長期持有context的引用,造成內(nèi)存泄露。所以動態(tài)檢測內(nèi)存泄露的一個簡單思路就是隨意操作APP,最后返回首頁,然后用MAT檢測,查看是否存在Activity多于一個或者Activity不正常存在的問題。 參考資料 |
|
|
來自: icecity1306 > 《開發(fā)資料》