Android常用檢查內(nèi)存泄漏,過度繪制的工具

內(nèi)存溢出(out of memery)

定義:APP運行時占用的內(nèi)存超出系統(tǒng)分配給該APP的內(nèi)存,就會出現(xiàn)內(nèi)存溢出。

原因:

遞歸(解決方法:增加條件),

死循環(huán)(解決方法:增加循環(huán)時間)

圖片加載(主要原因)超大圖片(利用壓縮工具壓縮圖片,裁剪,Glide,LRU算法)大量加載圖片并沒有及時做回收或銷毀處理

Fragment大量加載,未做好回收、解除綁定的處理(用replace方法)
大量的內(nèi)存泄漏

內(nèi)存泄漏

定義:當(dāng)activity銷毀后,gc在回收該實例的時候,發(fā)現(xiàn)該activity被其他對象持有引用,導(dǎo)致該activity不能被回收,出現(xiàn)內(nèi)存泄漏。

檢測:

1,在Android studio3.0以前,在下邊有一個Android Monitor,在Android studio3.0以后,將其改為了Android profiler,里邊可以分析CPU使用率,內(nèi)存、包括網(wǎng)絡(luò)狀態(tài),一般檢測內(nèi)存泄漏,只需要點擊memory,然后確保移動端啟動的程序和studio工具正確連接,如果要檢測當(dāng)前頁面是否存在泄漏問題,只需要將該activity finish,然后底部有一個小垃圾桶,他是起到手動觸發(fā)gc的功能,通過手動回收,然后再去包下查看該應(yīng)用當(dāng)前存留的實例,如果剛剛finish并且gc的activity仍然存在,證明在這個activity當(dāng)中存在內(nèi)存泄漏。點擊額外生成的activity(一般是后邊帶有$這個符號),一般在studio右邊會有泄漏原因的提示,當(dāng)然具體位置還需要程序員通過經(jīng)驗判斷,主動到項目業(yè)務(wù)中查詢。

2,可以使用leakcanary框架,這個相對比較簡單,只需要添加依賴,在application啟動的時候,判斷是否有l(wèi)eakcanary對該進(jìn)程泄漏的監(jiān)聽,如果沒有,在程序啟動的時候安裝leakcanary即可。

常見案例

1,handler耗時引發(fā)的內(nèi)存泄漏

當(dāng)activity當(dāng)中存在handler接收耗時的消息時,比如我們一般在網(wǎng)絡(luò)請求切換線程時,經(jīng)常使用到handler,假設(shè)消息還沒有發(fā)送完成,但是頁面已經(jīng)被關(guān)閉,也就說activity已經(jīng)執(zhí)行了ondestroy方法。當(dāng)gc回收時,會出現(xiàn)該activity不能被回收的情況,導(dǎo)致內(nèi)存泄漏。
解決辦法:當(dāng)activity銷毀的時候,調(diào)用handler的removeCallbacksAndMessages方法,移除消息任務(wù),然后將handler對象及線程置空。

2,內(nèi)部類引發(fā)的內(nèi)存泄漏(當(dāng)然handler或子線程一般也作為內(nèi)部類使用)

因為java當(dāng)中,內(nèi)部類默認(rèn)持有外部類的引用,當(dāng)外部類銷毀后,一旦gc回收該實例,發(fā)現(xiàn)內(nèi)部類持有他的引用而導(dǎo)致不能回收該實例,出現(xiàn)內(nèi)存泄漏的情況。
解決方法:將內(nèi)部類改為靜態(tài)內(nèi)部類,因為靜態(tài)內(nèi)部類生命周期和應(yīng)用一樣長,所以當(dāng)退出程序的時候會一同回收該實例,并不會影響外部類的回收。

3,單例導(dǎo)致的內(nèi)存泄漏

因為在使用單例的時候,經(jīng)常會傳入一個本類的上下文對象,而單例是靜態(tài)的,生命周期和application一樣長,當(dāng)activity銷毀的時候,該單例持有activity的引用導(dǎo)致其不能被回收,出現(xiàn)內(nèi)存泄漏。
解決方法:在使用上下文的時候,傳全局上下文。

4,資源未關(guān)閉

Cursor,stream,database,Butterknife,broadcastreciver,bindservice,eventBus
比如這些東西在使用完成后,需要進(jìn)行close或者Unbind處理,以節(jié)省內(nèi)存

5,Bitmap對象不在使用時調(diào)用recycle()釋放內(nèi)存

6,Timer計時器、動畫,

因為這些涉及耗時問題,如果activity銷毀,而該任務(wù)并未執(zhí)行完成,會導(dǎo)致內(nèi)存泄漏,所以一般在activity中如果使用到這些耗時任務(wù),需要在activity銷毀時,做對應(yīng)處理,比如調(diào)用timer的cancel方法,或者動畫的cancel方法并將對象置空

7,一些監(jiān)聽器的內(nèi)存泄漏

比如說我們給edittext設(shè)置輸入文字監(jiān)聽時,當(dāng)監(jiān)聽到文字發(fā)生變化,我們通過獲取變化后的文字執(zhí)行了耗時任務(wù)(比如獲取到edittext里的內(nèi)容上傳服務(wù)器),當(dāng)耗時任務(wù)未執(zhí)行完成activity銷毀了,會引發(fā)內(nèi)存泄漏,所以在onDestory時,取消注冊,比如說editText調(diào)用removeTextChangedListener方法

8,Rxjava的內(nèi)存泄漏:

因為rxjava采用的是觀察者模式,當(dāng)請求到數(shù)據(jù)后會根據(jù)訂閱關(guān)系將數(shù)據(jù)發(fā)送到訂閱者,而如果這時訂閱者已經(jīng)銷毀,就會出現(xiàn)引用該對象導(dǎo)致其不能被回收的情況,出現(xiàn)內(nèi)存泄漏,rxjava2發(fā)布的時候也發(fā)現(xiàn)了這個問題,所以在回調(diào)當(dāng)中,新增加了onSubcribe回調(diào),同時返回了一個disposable對象,可以通過判斷disposable里的isDisposed來確定當(dāng)前的訂閱關(guān)系,如果訂閱關(guān)系中的訂閱者已經(jīng)不存在且當(dāng)前訂閱關(guān)系存在,解除訂閱關(guān)系,并終止數(shù)據(jù)的發(fā)送。

9,webView引發(fā)的內(nèi)存泄漏:

因為webview在使用的時候一般持有activity的引用,我們一般在activity的onDestroy方法中調(diào)用mWebView.destroy();來釋放webview。如果在onDetachedFromWindow之前調(diào)用了destroy那就肯定會無法正常反注冊了,也就會導(dǎo)致內(nèi)存泄漏。所以在銷毀webview前一定要先在onDetachedFromWindow中將webview從它的父view中移除,再調(diào)用destroy方法中調(diào)用webview的destroy,我開發(fā)的時候在5.1以上的手機(jī)上發(fā)現(xiàn)這種問題比較多,因為現(xiàn)在5.1以下適配的比較少了,基本沒咋注意。

10,線程導(dǎo)致的內(nèi)存泄漏:

一般使用子線程都會創(chuàng)建一個內(nèi)部類對象,而創(chuàng)建線程一般執(zhí)行耗時任務(wù),所以這個內(nèi)部類默認(rèn)持有外部類的引用,如果耗時任務(wù)在activity銷毀的時候未執(zhí)行完成,會因為持有外部類引用導(dǎo)致外部類不能被回收

11,MVP內(nèi)存泄漏:

MVP實現(xiàn)了view層和model層的徹底分離,P層作為view層和model層的中間層,view層需要通過P層執(zhí)行耗時任務(wù),P層一般持有view的引用,如果m層的耗時任務(wù)還沒有執(zhí)行完成,這時候view層被銷毀了,會出現(xiàn)由于p持有view的引用導(dǎo)致view不能被回收,出現(xiàn)內(nèi)存泄漏的問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 我的CSDN: ListerCi我的簡書: 東方未曦 一、引言 一般情況下Android的內(nèi)存泄漏是因為,存在引用...
    東方未曦閱讀 3,950評論 1 10
  • Android 內(nèi)存泄漏總結(jié) 內(nèi)存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問題。內(nèi)存泄漏...
    _痞子閱讀 1,700評論 0 8
  • 【Android 內(nèi)存泄漏】 引用: ★★★ 【知識必備】內(nèi)存泄漏全解析,從此拒絕ANR,讓OOM遠(yuǎn)離你的身邊,跟...
    Rtia閱讀 987評論 0 2
  • Android 內(nèi)存泄漏總結(jié) 內(nèi)存管理的目的就是讓我們在開發(fā)中怎么有效的避免我們的應(yīng)用出現(xiàn)內(nèi)存泄漏的問題。內(nèi)存泄漏...
    apkcore閱讀 1,306評論 2 7
  • 時間就像一把篩子,總能剔除記憶中瑣碎的憂傷,把那些美好的記憶留在原地熠熠生光,被記憶漂洗過的歲月珍藏了一生中多少純...
    抽一支閱讀 711評論 1 35

友情鏈接更多精彩內(nèi)容