波尔多干红:Android Studio 內存泄漏分析指南 [復制鏈接]

2019-9-29 09:59
SoftwareGames 閱讀:290 評論:0 贊:0
Tag:  內存泄漏

恋恋波尔多 www.luaogj.com.cn 最近在優化公司的項目,想針對內存泄漏進行分析一下,查閱網上的一些資料,發現苦逼的是,資料一大堆,但是內容都差不多,至今未找到一篇實戰的內存泄漏分析,全部停留在理論知識上,最后查閱了一些外文文獻,才有了一點思路,好吧!既然沒有實戰分析,我就做第一人,把我學到的分享出來,希望對你們有幫助,當然有說的不對的,望各位指出來~

內存泄漏原因

當應用不需要某對象時候,忘記釋放分配的內存,該對象仍然保持被引用狀態(當對象擁有強引用,GC無法回收),從而導致內存泄漏

泄漏的源頭

泄漏的源頭有很多,有開源的第三方框架引起的、android系統自身造成的如webview的內存泄漏,還有一個是我們可以控制的就是自身編碼引起的內存泄漏,這也是我們可以避免的,一下情況容易出現內存泄漏

一、 Context 引起的內存泄漏

常見問題:

這個是最常見的,因為Activity經常要用到上下文Context,很有可能Activity作為Context傳遞給某些類,Activity生命周期結束之后,某些類仍然存活并保持著該Activity的引用,保持引用就無法被回收。從而導致內存泄漏

解決方案:

  1. 下次如果要傳入context給某些類的時候,最好是用ApplicationContext,這樣可以有效避免內存泄漏

  2. 在界面銷毀的時候,手動釋放掉引用過activity的context

二、Static 靜態變量

常見問題:

我們有時候會為了方便,設置某個Activity或者View為靜態變量,但是你要知道,static變量是要貫穿整個應該的生命周期,就是意味著即使Activity銷毀,static變量也不會銷毀,所以,如果你把View或者Activity設置為靜態變量,這會導致當前的Activity會一直存在,從而導致內存泄漏

解決方案:

  1. 盡量避免使用static變量

  2. 如果非要使用的話,記得在界面銷毀的時候,把靜態變量也釋放掉,簡單說就是把靜態變量置空,如staticView=null

三、非靜態內部類、匿名內部類持有外部類的引用

常見問題:

我們在使用AsyncTash、Handler、TimerTask、Thread的時候,為了方便,直接new一個匿名內部類對象,殊不知我們在new一個的時候,編譯器在編譯的時候會自動為內部類的構造方法加上外包類的引用,所以這些匿名內部類會持有Activity,當這些匿名內部類處理非常耗時的操作時候,就算Activity生命周期結束,也不會被銷毀,這就會造成內存泄漏

解決方案:

  1. 當Activity銷毀的時候,對不需要的匿名內部類進行任務停止操作

  2. 使用靜態內部類,靜態內部類內部使用弱引用來引外外部類,這樣當Activity銷毀的時候,弱引用是可以被回收的

四、其他引起的泄漏

  1. 我們在使用系統服務的時候,比如注冊了一些廣播監聽,在使用完后,要釋放掉

  2. 我們在給View繪制動畫的時候,View被動畫持有,而Activity又被View持有引用,導致Activity也無法釋放。所以在Activity銷毀時,調用animator.cancel()來停止動畫

內存泄漏分析-實戰篇

這個才是盡頭的重頭戲,前面寫的只是對網上文獻的一些總結

分析工具

  1. MAT :eclipse時代的分析工具,具體分析實戰可以參考這篇文章

  2. LeakCanary: Square開源的內存泄漏探測器,具體使用參考這篇文章

  3. Android Monitor:Android Studio 自帶的分析工具,今天的重頭戲

Android Monitor

  1. 生成HPROF文件,點擊紅框中有綠色下載箭頭的按鈕(Dump java Heap),這個會生成以hprof結尾的文

  2. 生成的效果如下圖,簡單介紹一下界面功能

Android Studio 內存泄漏分析指南

功能描述:

名稱描述
Total Count該類的實例總數
Heap Count所選擇的堆中該類的實例的數量
Sizeof單個實例所占空間大?。ㄈ綣扛鍪道伎占浯笮〔灰謊螄允?)
Shallow Size堆里所有實例大小總和(Heap Count * Sizeof)
Retained Size該類所有實例所支配的內存大小
Instance具體的實例
Reference Tree所選實例的引用,以及指向該引用的引用。
DepthGC根節點到所選實例的最短路徑的深度
Shallow Size所選實例的大小
Dominating Size所選實例所支配的內存大小

3. 也許你看完這些也還是一頭霧水,不知道怎么分析,沒關系,我們不就是要找到內存泄漏的源頭嘛,來看這里,要開始放大招啦,看到上圖中最右邊的 Analyzer Tasks,點擊這個版塊,這個版塊就是主要的查找內存泄漏版塊

Android Studio 內存泄漏分析指南

4. 啟動頁很簡單,點擊綠色運行按鈕就好,之后會在下面列出可能存在內存泄漏的Activity,如果沒顯示,說明啟動的Activity中沒有內存泄漏

5. 查看引用樹(Reference Tree),都是根據這個查找內存泄漏的具體地方的

6. 一般有類似三角形的,就是一直被引用這,導致內存泄漏,找到對應的地方也很簡單,右鍵項目點擊Jump to Source就會打開對應泄漏源碼的地方啦,然后我們在根據上面說的泄漏原因,及解決辦法修正就好啦

Android Studio 內存泄漏分析指南

Android Studio 內存泄漏分析指南



我來說兩句
您需要登錄后才可以評論 登錄 | 立即注冊
facelist
所有評論(0)
領先的中文移動開發者社區
18620764416
7*24全天服務
意見反?。[email protected]

掃一掃關注我們

Powered by Discuz! X3.2© 2001-2019 Comsenz Inc.( 恋恋波尔多 )