1. 程式人生 > >Android 記憶體監測工具 DDMS --> Heap

Android 記憶體監測工具 DDMS --> Heap

在DDMS裡檢查heap的使用情況

Dalvik Debug Monitor Server(DDMS)是主要的Android除錯工具之一,也是ADT Eclipse plug-in 的一部分,獨立的程式版本也可以在Android SDK的根目錄下的tools/下面找到。關於DDMS更多的資訊,請參考使用DDMS

我們來使用DDMS檢查這個應用的heap使用情況。你可以使用下面的兩種方法啟動DDMS:

  • from Eclipse: click Window > Open Perspective > Other... > DDMS
  • or from the command line: run ddms
    (or ./ddms on Mac/Linux) in the tools/ directory

Android 記憶體監測工具 DDMS --> Heap

在左邊的面板選擇程序com.example.android.hcgallery,然後在 工具條上邊點選Show heap updates按鈕。這個時候切換到DDMS的VM Heap分頁。它會顯示每次gc後heap記憶體的一些基本資料。要看第一次gc後的資料內容,點選Cause GC按鈕:

Android 記憶體監測工具 DDMS --> Heap

我們可以看到現在的值(Allocated列)是有一些超過8MB。現在滑動相片,這時看到 資料在增大。因為只有僅僅13個相片在程式裡邊,所以洩露的記憶體只有這麼大。在某種程度上來說,這時最壞的一種記憶體洩露,因為我們沒法得到 OutOfMemoryError來提醒我們說現在記憶體溢位了。

生成heap dump

我們現在使用heap dump來追蹤這個問題。點選DDMS工具條上面的Dump HPROF檔案按鈕,選擇檔案儲存位置,然後在執行hprof-conv。在這個例子裡我們使用獨立的MAT版本(版本1.0.1),從MAT站點下載

如果你使用ADT(它包含DDMS的外掛)同時也在eclipse裡面安裝了MAT,點選“dump HPROF”按鈕將會自動地做轉換(用hprof-conv)同時會在eclipse裡面開啟轉換後的hprof檔案(它其實用MAT開啟)。

用MAT分析heap dumps

啟動MAT然後載入剛才我們生成的HPROF檔案。MAT是一個強大的工具,講述它所有的特性超出了本文的範圍,所以我只想演示一種你可以用來檢測 洩露的方法:直方圖(Histogram)檢視。它顯示了一個可以排序的類例項的列表,內容包括:shallow heap(所有例項的記憶體使用總和),或者retained heap(所有類例項被分配的記憶體總和,裡面也包括他們所有引用的物件)。

Android 記憶體監測工具 DDMS --> Heap

如果我們按照shallow heap排序,我們可以看到byte[]例項在頂端。自從Android3.0(Honeycomb),Bitmap的畫素資料被儲存在byte數組裡 (之前是被儲存在Dalvik的heap裡),所以基於這個物件的大小來判斷,不用說它一定是我們洩露掉的bitmap。

右擊byte[]類然後選擇List Objects > with incoming references。它會生成一個heap上的所有byte陣列的列表,在列表裡,我們可以按照Shallow Heap的使用情況來排序。

選擇並展開一個比較大的物件,它將展示從根到這個物件的路徑--就是一條保證物件有效的鏈條。注意看,這個就是我們的bitmap快取!

Android 記憶體監測工具 DDMS --> Heap

MAT不會明確告訴我們這就是洩露,因為它也不知道這個東西是不是程式還需要的,只有程式設計師知道。在這個案例裡面,快取使用的大量的記憶體會影響到後面的應用程式,所以我們可以考慮限制快取的大小。

使用MAT比較heap dumps

除錯記憶體洩露時,有時候適時比較2個地方的heap狀態是很有用的。這時你就需要生成2個單獨的HPROF檔案(不要忘了轉換格式)。下面是一些關於如何在MAT裡比較2個heap dumps的內容(有一點複雜):

  1. 第一個HPROF 檔案(using File > Open Heap Dump ).
  2. 開啟 Histogram view.
  3. 在Navigation History view裡 (如果看不到就從Window > Navigation History找 ), 右擊histogram 然後選擇Add to Compare Basket .
  4. 開啟第二個HPROF 檔案然後重做步驟2和3.
  5. 切換到Compare Basket view, 然後點選Compare the Results (檢視右上角的紅色"!"圖示)。

總結

這本篇文章裡面,我展示了Allocation Tracker和heap dumps是如何給你一種對程式記憶體使用的感性認識。我也展示了Eclipse Memory Analyzer(MAT)可以幫助追逐我們程式裡面的記憶體洩露問題。MAT是一個強大的工具,我也僅僅觸碰了一些皮毛,如果你想學習更多內容,我建議讀 一些下面的文章: