1. 程式人生 > >排查記憶體洩漏最簡單和直觀的方法

排查記憶體洩漏最簡單和直觀的方法


 
  

記憶體洩漏無疑會嚴重影響使用者體驗,一些本應該廢棄的資源和物件無法被釋放,導致手機記憶體的浪費,app使用的卡頓,那麼如何排查記憶體洩漏呢?

當然,首先我門有google的官方文件可以參考:

排查記憶體洩漏官方文件

官方文件(二)

大部分部落格的方法也來自於此。總的來說,就是使用android studio 的monitor memory功能監測app主程序佔用的記憶體,觸發GC操作,而後觀察記憶體的佔用情況,如果在使用的過程中記憶體不斷增加,沒有回落,很有可能發生了記憶體洩漏,這時候就需要匯出記憶體分配的具體詳情進行深入分析了。

記憶體監測曲線

但是事實上,通過觀察這個記憶體曲線的曾場來或者是觀察allocate tracker中的allocate data數值的增長來檢測是否有記憶體洩漏問題,真的很玄,因為往往記憶體洩漏發生了,但是GC仍然可以通過回收其他物件的方式騰出空間,導致這個資料的變化基本看不出來,甚至是減小的,所以我覺得這種方式,就像是讓你用手掌去感知嬰兒的體溫,去檢測確定這個嬰兒有沒有發燒一樣,非常不靠譜不準確。

那麼,重點來了,我的方法,簡單直觀,保準你一學就會!

第1步:檢測記憶體洩漏

先說一個terminal指令: 

adb shelldumpsys meminfo (pid name)

這條指令是用來查詢這個程序所佔用的記憶體的具體詳情的,通過這條指令可以看到當前app在手機中佔用的具體的堆記憶體大小,view的數量,activity的數量,等等。如下圖:

程序記憶體分配詳情

其中activity數目是非常關鍵的一個資訊,可以幫助我們快速地檢測出記憶體洩漏。我們可以反覆地進入退出需要測試的目標activity,如果在反覆進入退出之後,用terminal執行上面的語句查詢當前的記憶體情況,如果發現activity數量一直在增長,那麼記憶體洩露一定是發生了!

第2步:定位記憶體洩漏的原因

記憶體洩漏已經發生,如何定位原因呢?

方法1:  MAT定位

如下圖,在android studio中開始memory monitor,點選init GC,反覆進入退出發生了記憶體洩漏的activity,這時候點選生成記憶體檔案,這之後android studio會自動開啟生成的.hprof檔案。選中該檔案轉化成標準的hrof檔案。

用MAT工具開啟生成的.hprof檔案,點選如下所示的圖示,可以看到記憶體中的物件列表。

考慮到大記憶體的洩漏都是因為Activity被destroy之後卻仍然被其他物件持有而造成的,因此首先解決棘手問題,直接搜尋Activity,如下。發現有Activity的例項個數是3,跟實際不符,明顯這個activity導致記憶體洩漏了,按照如圖的方式找到它的引用,也就是導致記憶體洩漏的幕後凶手!

可以看到這個例子中的記憶體洩漏是由一個HandlerThread引發的,那麼找到這個問題的位置,在合適的地方(如ondestroy)將這個handler thread釋放即可。

方法2: Android Studio自帶的Analyzer Tasks

如下圖所示: 在android studio中開啟生成的hprof檔案,在右側邊欄會出現的Analyzer Tasks工具,點選執行圖示,即可出現檢測分析的結果,得到哪些activity被洩漏了,這些被洩漏的activity被誰引用了。

可以看到記憶體洩漏由AsyncHandler引起,需要在activity生命週期結束的時候進行釋放。

android studio自帶的分析工具

方法2不用安裝MAT工具,更加便捷哦~

作者:平凡小天地 連結:http://www.jianshu.com/p/f4bc1afecff8 來源:簡書 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。