Android 內存監測工具 DDMS --> Heap

用 Heap監測應用進程使用內存情況的步驟如下:
1. 啓動eclipse後,切換到DDMS透視圖,並確認Devices視圖、Heap視圖都是打開的;
2. 將手機通過USB鏈接至電腦,鏈接時需要確認手機是處於“USB調試”模式,而不是作爲“Mass Storage”;
3. 鏈接成功後,在DDMS的Devices視圖中將會顯示手機設備的序列號,以及設備中正在運行的部分進程信息;
4. 點擊選中想要監測的進程,比如system_process進程;
5. 點擊選中Devices視圖界面中最上方一排圖標中的“Update Heap”圖標;
6. 點擊Heap視圖中的“Cause GC”按鈕;
7. 此時在Heap視圖中就會看到當前選中的進程的內存使用量的詳細情況。
說明:
a) 點擊“Cause GC”按鈕相當於向虛擬機請求了一次gc操作;
b) 當內存使用信息第一次顯示以後,無須再不斷的點擊“Cause GC”,Heap視圖界面會定時刷新,在對應用的不斷的操作過程中就可以看到內存使用的變化;
c) 內存使用信息的各項參數根據名稱即可知道其意思,在此不再贅述。
  如何才能知道我們的程序是否有內存泄漏的可能性呢。這裏需要注意一個值:Heap視圖中部有一個Type叫做data object,即數據對象,也就是我們的程序中大量存在的類類型的對象。在data object一行中有一列是“Total Size”,其值就是當前進程中所有Java數據對象的內存總量,一般情況下,這個值的大小決定了是否會有內存泄漏。可以這樣判斷:
a) 不斷的操作當前應用,同時注意觀察data object的Total Size值;
b) 正常情況下Total Size值都會穩定在一個有限的範圍內,也就是說由於程序中的的代碼良好,沒有造成對象不被垃圾回收的情況,所以說雖然我們不斷的操作會不斷的生成很多對 象,而在虛擬機不斷的進行GC的過程中,這些對象都被回收了,內存佔用量會會落到一個穩定的水平;
c) 反之如果代碼中存在沒有釋放對象引用的情況,則data object的Total Size值在每次GC後不會有明顯的回落,隨着操作次數的增多Total Size的值會越來越大,
  直到到達一個上限後導致進程被kill掉。
d) 此處已system_process進程爲例,在我的測試環境中system_process進程所佔用的內存的data object的Total Size正常情況下會穩定在2.2~2.8之間,而當其值超過3.55後進程就會被kill。

 

來自: http://apps.hi.baidu.com/share/detail/32190286

 


在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

 

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

 

 

我們可以看到現在的值(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(所有類實例被分配的內存總和,裏面也包括他們所有引用的對象)。

 

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

 

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

 

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

 

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是一個強大的工具,我也僅僅觸碰了一些皮毛,如果你想學習更多內容,我建議讀 一些下面的文章:

發佈了4 篇原創文章 · 獲贊 2 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章