1. 程式人生 > >Android studio + MAT記憶體分析優化 一

Android studio + MAT記憶體分析優化 一

        關於記憶體分析和優化,是我們app從開始到結束上線一直都要關注的問題。但是我發現我接觸過得專案和公司,都是在APP成型之後,或者快上線了,才會去關注app記憶體使用情況。派專人去分析每個頁面,每個動作是否會觸發記憶體洩漏,ui卡頓等問題。個人認為這是個非常不好的習慣,記憶體分析優化,UI卡頓等應該是我們每個程式設計師編碼的時候就刻意的去注意的問題。我們每完成一個需求,或者沒新增一個邏輯,都要去想到這行程式碼會不會影響記憶體洩漏,ui卡頓。比如單例我們傳的context,是activity的還是application的。我們的handler使用完是否需要在ondestory()裡removeallcallBACK()。開啟的執行緒什麼時候回銷毀。使用的Rxjava開啟的流,最後都要呼叫dispose()等等。都是我們在編碼的時候要注意的。不然很容易造成洩漏。

最近再做的一個華為音樂的專案,需要盤查記憶體洩漏和使用的情況。結合實際情況一步步分析優化的記錄和總結。

今天我們使用的是Android studio 和 MAT來分析優化記憶體,具體怎麼使用我們先來看看Androidstudio 和 MAT各自起到什麼作用。

首先我們來介紹一下Android studio能幫我們做什麼?

AS大家都比較熟悉了,但是AS不同的版本可能會有一點差異,比如我在公司使用的都是3.1版本的AS,我自己電腦上裝的是2.3的。AS3.0以上版本和之前的有很大差別,具體大家可以去搜搜看。。但是今天我們還是用2.3的來分析。當然在3.0上也是通用的,只是按鈕的位置,形狀可能會有些差別。

首先寫了一個洩漏的例子,來幫助我們分析。

1.比如我們有兩個Activity,A和B。開啟專案從activityA跳轉到activityB等一系列的可能還有記憶體洩漏的操作,再回到activityA。這時候我們手動GC如圖:


多GC幾次,等到我們的memory穩定了,之後點選我們的dump按鈕,生成.hprof檔案,自動開啟。之後我們也可以在左上角簡單的看看一下具體的例項,記憶體佔用等。但是太多不容易分析。

2.這時候我們得到的.hprof檔案是不標準的,我們要轉換成標準的給我們的MAT使用。看圖:


生成標準的hprof檔案之後,我們的as的工作就可以停止了。

(命令列方式生成標準的hprof檔案,

1.在as的sdk-》platform-tools-》開啟CMD視窗,

2.輸入hprof-conv 原來.hprof 目標.hprof,

3.在sdk下面生成目標.hprof檔案是標準的)

接下來就是我們的MAT了。

MAT的起到什麼作用?

我們得到標準的hprof檔案之後,我們就可以拿著我們的hprof檔案去分析了。

MAT工具全稱為Memory Analyzer Tool,一款詳細分析Java堆記憶體的工具,該工具非常強大,為了使用該工具,我們需要hprof檔案。但是該檔案不能直接被MAT使用,需要進行一步轉化,可以使用hprof-conv命令來轉化,但是AndroidStudio可以直接轉化,轉化方法如下:

開啟MAT工具,File->Open File選擇我們剛才生成的test.hprof檔案。如圖:


我們之關係我們使用的功能,具體其他功能請找傳送門。。

我們比較關係的功能Histogram是這個,點選進去。可以輸入我們要搜尋的activity,因為洩漏最終導致的問題就是我們的activity關閉了,但是記憶體不能夠回收我們不用的activity。就是我們的activity例項被佔用了,具體被誰佔用了。接下來。。。


選中我們應該被銷燬卻沒有銷燬的activity例項,右鍵-》listobject-》with incoming references


然後對引用的物件進行軟引用,虛引用,軟引用過濾,我們之關係的是強引用。所以有上圖。就會列出引用我們activity的類,這時候我們可以查詢我們自己使用的類,,看看具體的類是不是有問題。

-------------------------------------------------------------------------------------------番外篇-------------------------------

基於上面的分析我們再來一個比較直觀的能看到我們app有多少activity和 view是沒有被銷燬的。沒有被GC回收的。。

具體操作:app一頓操作之後,按返回鍵,退到桌面,之後不用殺死程序,這時候我們手動GC,多GC幾次,,直到記憶體穩定。。然後按圖操作:


如圖開啟我們的記憶體使用功能,這個在AS3.0以上我真的沒找到,找了半天,找不到,不知被gogle放哪去了。。。。有知道的小夥伴可以留言告訴我一下,哈哈。

然後下圖:看到view的數量,和activity的數量,如果activity不為0,說明你的activity有洩漏。具體你就可以按照我們上面的方式去分析。


但是但是,,,,我找不到as 3.0 上這個功能的位置,,欲哭無淚咋辦呢。。。。不用怕我們有偉大的命令列。

操作流程都是一樣的,然後開啟我們的CMD命令,

輸入:adb shell dumpsys meminfo -d xxxapp包名。回車完事。

跟我們上圖一樣activity和view的數量都出來了

所以我們就講到這裡,下一篇給大家介紹一下leakcanary處理記憶體洩漏,,基本上這兩種處理記憶體洩漏的方法就能滿足我們的專案需求了。。。