分析工具:
1MAT
2Android Studio Memory-profiler
https://developer.android.com/studio/profile/memory-profiler#performance
3LeakCanary
https://github.com/square/leakcanary
Android內(nèi)存泄漏常見場景以及解決方案:
1、資源性對象未關(guān)閉
對于資源性對象不再使用時,應(yīng)該立即調(diào)用它的close()函數(shù),將其關(guān)閉胁黑,然后再置為null。例如Bitmap
等資源未關(guān)閉會造成內(nèi)存泄漏唇跨,此時我們應(yīng)該在Activity銷毀時及時關(guān)閉脏款。
2钮科、注冊對象未注銷
例如BraodcastReceiver、EventBus未注銷造成的內(nèi)存泄漏奄喂,我們應(yīng)該在Activity銷毀時及時注銷之剧。
3、類的靜態(tài)變量持有大數(shù)據(jù)對象
盡量避免使用靜態(tài)變量存儲數(shù)據(jù)砍聊,特別是大數(shù)據(jù)對象,建議使用數(shù)據(jù)庫存儲贰军。
4玻蝌、單例造成的內(nèi)存泄漏
優(yōu)先使用Application的Context,如需使用Activity的Context词疼,可以在傳入Context時使用弱引用進(jìn)行封
裝俯树,然后,在使用到的地方從弱引用中獲取Context贰盗,如果獲取不到许饿,則直接return。
5舵盈、非靜態(tài)內(nèi)部類的靜態(tài)實例
該實例的生命周期和應(yīng)用一樣長陋率,這就導(dǎo)致該靜態(tài)實例一直持有該Activity的引用,Activity的內(nèi)存資源
不能正郴嗤恚回收瓦糟。此時,我們可以將該內(nèi)部類設(shè)為靜態(tài)內(nèi)部類或?qū)⒃搩?nèi)部類抽取出來封裝成一個單例赴蝇,如
果需要使用Context菩浙,盡量使用Application Context,如果需要使用Activity Context句伶,就記得用完后置
空讓GC可以回收劲蜻,否則還是會內(nèi)存泄漏。
6考余、Handler臨時性內(nèi)存泄漏
Message發(fā)出之后存儲在MessageQueue中先嬉,在Message中存在一個target,它是Handler的一個引
用秃殉,Message在Queue中存在的時間過長坝初,就會導(dǎo)致Handler無法被回收。如果Handler是非靜態(tài)的钾军,
則會導(dǎo)致Activity或者Service不會被回收鳄袍。并且消息隊列是在一個Looper線程中不斷地輪詢處理消息,
當(dāng)這個Activity退出時吏恭,消息隊列中還有未處理的消息或者正在處理的消息拗小,并且消息隊列中的Message
持有Handler實例的引用,Handler又持有Activity的引用樱哼,所以導(dǎo)致該Activity的內(nèi)存資源無法及時回
收哀九,引發(fā)內(nèi)存泄漏剿配。解決方案如下所示:
1、使用一個靜態(tài)Handler內(nèi)部類阅束,然后對Handler持有的對象(一般是Activity)使用弱引用呼胚,這
樣在回收時,也可以回收Handler持有的對象息裸。
2蝇更、在Activity的Destroy或者Stop時,應(yīng)該移除消息隊列中的消息呼盆,避免Looper線程的消息隊列中
有待處理的消息需要處理年扩。
需要注意的是,AsyncTask內(nèi)部也是Handler機(jī)制访圃,同樣存在內(nèi)存泄漏風(fēng)險厨幻,但其一般是臨時性的。對于
類似AsyncTask或是線程造成的內(nèi)存泄漏腿时,我們也可以將AsyncTask和Runnable類獨立出來或者使用靜
態(tài)內(nèi)部類况脆。
7、容器中的對象沒清理造成的內(nèi)存泄漏
在退出程序之前圈匆,將集合里的東西clear漠另,然后置為null,再退出程序
8跃赚、WebView
WebView都存在內(nèi)存泄漏的問題笆搓,在應(yīng)用中只要使用一次WebView,內(nèi)存就不會被釋放掉纬傲。我們可以為
WebView開啟一個獨立的進(jìn)程满败,使用AIDL與應(yīng)用的主進(jìn)程進(jìn)行通信,WebView所在的進(jìn)程可以根據(jù)業(yè)
務(wù)的需要選擇合適的時機(jī)進(jìn)行銷毀叹括,達(dá)到正常釋放內(nèi)存的目的算墨。
9、使用ListView時造成的內(nèi)存泄漏
在構(gòu)造Adapter時汁雷,使用緩存的convertView净嘀。