1. 程式人生 > >android 應用記憶體分析MAT結合LeakCanary的分析OOM異常

android 應用記憶體分析MAT結合LeakCanary的分析OOM異常

朋友們在開發應用過程中,可能會碰到OOM異常,通常造成的原理是物件沒有及時釋放,或者載入Bitmap過多過大導致的。

一、匯入LeakCanary

使用的方法也十分的簡單

在Gradle檔案中加入

dependencies {
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' 
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' 
   testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' 
 }
然後在Application中的onCreate方法中加入
LeakCanary.install(this);

這樣就可以了

二、使用

使用起來也是十分的簡單 匯入之後基本不用管,在應用發生OOM異常時,LeakCanary會自動的生成hprof檔案,此時機器上會彈出通知,點開可以檢視到。 點選右上角share heap dump即可將hprof檔案傳送到電腦上。(hprof檔案的用處下面就會說到)

三、使用MAT工具檢視hprof檔案,分析記憶體佔用

Eclipse Memory Analysis Tools (MAT) 是一個分析 Java堆資料的專業工具,用它可以定位記憶體洩漏的原因。

下載地址:http://www.eclipse.org/mat/downloads.php

1、將前面LearkCanary收集的hprof檔案轉換:

1)在sdk-->tools目錄下按住shift 右鍵點選“在此處開啟命令列視窗”

 2)在開啟的命令列視窗中輸入hprof-conv xxxx.hprof nnnn.hprof

這裡xxxxx.hprof是learkcanary收集的hprof檔案 nnnn.hprof是你要生成的檔案,名字隨意取

2、安裝完成後,開啟軟體,點選左上角的file-->Open heap Dump...

開啟上面轉換後的檔案可以看到如下餅狀圖

這裡可以大致的檢視到記憶體佔用情況

點選Leak Suspects

會提示可能的原因

其實這裡已經可以大概的看出原因了,是資源引用的問題

點選Histogram可以看到例項類的列表

右鍵點選

可以看到有outgoing references、incoming references可以檢視當前物件引用和被引用的情況。

如果發現一個物件被靜態物件引用,則通常它是不會被回收的。

在incoming中,可以看到,byte[]之所以佔用這麼多記憶體,全部都是因為被用於載入圖片

而我正是在程式碼中無限迴圈的載入圖示到一個集合中,造成OOM異常。

while (true){

            Resources res = getResources();
            Bitmap bitmap = ((BitmapDrawable) res.getDrawable(R.drawable.j)).getBitmap();
            list.add(bitmap);

        }

基本找出了OOM異常的原因。

在實際開發中,Eclipse和Android Studio中都可以手動的去收集hprof檔案,方法網上也有很多,在分析記憶體佔用時,有很大幫助,特別是Android Studio中自帶的記憶體檢視工具,可以看到記憶體實時的使用波形圖,如果在應用程式執行中,發現重複開啟後關閉一個頁面,記憶體佔用一直上升的,通常此頁面便有可能造成OOM異常。此外,如果記憶體波開圖經常出現比較大的抖動,說明GC執行頻繁,可能會影響應用效能和體驗。

使用的一點體會,分享給大家,如有錯誤,請大家指正。