當然,首先我們有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工具,更加便捷哦~
希望這篇
文章可以幫助你快速發現和定位內存泄漏。