1. 程式人生 > >在Eclipse中使用MAT分析Android程式記憶體使用狀況(轉)

在Eclipse中使用MAT分析Android程式記憶體使用狀況(轉)

對於Android這種手持裝置來說,通常不會帶有太大的記憶體,而且一般使用者都是長時間不重啟手機,所以編寫程式的時候必須要非常小心的使用記憶體,儘量避免有記憶體洩露的問題出現。通常分析程式中潛在記憶體洩露的問題是一件很有難度的工作,一般都是由團隊中的資深工程師負責,而且隨著程式程式碼量的提高,難度還會逐步加大。

今天要介紹一個在Eclipse中使用的記憶體分析工具——MAT(Eclipse Memory Analyzer,主頁在http://www.eclipse.org/mat/)。它是一個功能非常豐富的Java堆轉儲檔案分析工具,而且簡單易用,只需點幾下下滑鼠就可以生成一個專業的分析報告。更重要的是,它和DDMS能夠無縫整合,可以幫助你發現Android程式中潛在的記憶體洩露問題,同時可以協助你優化程式,更加高效的使用記憶體。

一、安裝 MAT

MAT是Eclipse中的一個外掛,所以安裝非常簡單。

首先,通過 Help -> Install Software... 啟動軟體安裝頁面:

接下來選擇你想要安裝的 MAT 的功能。因為只需要在Eclipse中使用MAT,所以這裡只需要選擇Memory Analyzer for Eclipse IDE。特別提一下,Memory Analyzer (Chart) 這個功能是一個可選的安裝項,主要用來將資料生成相關的視覺化報表,通常這樣更加直觀,更容易發現問題。

剩下的就一路點Next就好了。

二、幾個基本概念

要想看懂MAT生成的報告,還需要掌握幾個基本的概念。

Java記憶體回收

Java程式中,記憶體空間中垃圾回收的工作是由垃圾回收器(Garbage Collector,GC)完成的。它的核心思想是,對虛擬機器中堆記憶體空間中的物件進行識別,如果物件正在被別的物件引用,那麼稱其為存活物件;反之,如果物件不再被任何別的物件所引用,則為垃圾物件,可以回收其佔據的空間,用於再分配。

對於Android程式來說,其Dalvik虛擬機器本身就是一個類Java的虛擬機器實現,也具有主動垃圾回收功能。

GC根物件(GC Root)

在垃圾回收機制中,有一組特殊的物件被稱為根物件,它們是一組被虛擬機器直接引用的物件。比如,正在執行的執行緒物件,系統呼叫棧裡面的物件,以及被系統類載入器所載入進來的物件。堆空間中的每個物件都是由一個根物件為起點被層層引用的,只有它們引用別的物件,沒有其它任何物件可以引用它們。因此,如果一個物件還被某一個存活的根元素所直接或間接的引用,就會被認為是存活物件,不能被回收,進行記憶體釋放。

Shallow Size和Retained Size

1)Shallow Size(表面大小)是指物件本身所佔用的記憶體空間大小,不包含被其引用到的物件所佔的記憶體空間。一個物件的Shallow Size取決於這個物件的例項變數的型別和個數。一個數組物件的Shallow Size是陣列中儲存的物件的Shallow Size乘以陣列元素的個數。一個集合物件的Shallow Size是集合內所有物件的Shallow Size之和。

2)Retained Size(保留大小)是指物件本身的Shallow Size加上從其本身開始所能直接或間接訪問到的,且只能由其開始才能訪問到的所有物件的Shallow Size之和。這個大小就表明,如果將這個物件釋放之後,垃圾回收器所能回收的所有記憶體大小。

下面舉個例子說明,假設物件的引用關係如下:

第一張圖中計算物件obj1的Retained Size要包含obj1、obj2和obj4,因為obj3和obj5還可以被根物件引用到,所以不能被包含進來。而在第二張圖中,obj3只能被obj1間接引用到,所以要包含進來。

支配樹(Dominator Tree)

支配樹的定義是,如果在物件引用關係圖中,從任意一個物件,如果想訪問物件Y的話,必須通過物件X,那麼物件X就處於物件Y的支配(Dominate)地位。

可以看出來,支配樹的概念其實和前面的Retained Size是相關聯的。某個物件的Retained Size就是從這個物件開始,以及從它開始所有支配樹子節點的Shallow Size之和。

而且,所有根節點一定是支配樹中的頂層節點,反之不一定。

堆轉儲檔案(Heap Dump)

所謂堆轉儲檔案,是在一個特定時間點,對Java程序的記憶體快照檔案。它包含了快照被觸發時,Java物件和類在堆中的使用情況。由於快照只是一瞬間的事情,所以只能包含在這個時間點各個物件之間的引用關係,而無法知道一個物件在什麼時間點,由哪個方法建立等資訊。

MAT其實就是一個通用的Java堆轉儲檔案的分析工具,而通過Android自帶的DDMS,可以獲得指定裝置上指定程序的堆轉儲檔案,將兩者結合起來剛好可以達到分析Android程式記憶體使用狀況的目的。

三、如何分析

首先,將你想要分析的程式啟動起來,並確保其是可除錯的(即在AndroidManifest.xml檔案中申明android:debuggable=”true”)。

然後,用DDMS收集Android裝置上,你想除錯程式的堆轉儲檔案。這步也很簡單,在DDMS中,選取你的程式,並點選Dump HPROF file:

DDMS生成轉儲檔案可能要花一點時間,請耐心等待一會。當轉儲檔案生成好了之後,Eclipse會自動呼叫MAT進行分析,並生成報告:

在這份報告中,我們可以獲得如下資訊:

1)Histogram:列出了當前程式中每個類被例項化出了多少個物件;

2)Dominator Tree:列出了當前程式中各個活動物件間的支配樹關係;

3)TopConsumer:列出了當前程式中Retained Size最大的前幾個物件等資訊;

4)DuplicateClasses:列出了當前程式中是否有相同的類被不同的類載入器載入的情況。

Histogram和Dominator Tree的區別是分析問題的角度不一樣,Histogram是站在類的角度上去分析,而Dominator Tree是站的物件例項的角度上去分析,Dominator Tree可以更方便的看出各個物件間的引用關係。

有了這些武器之後,分析記憶體洩露問題就變得得心應手了,一般的流程如下:

1)在Histogram和Dominator Tree檢視中,根據Retained Heap排序,找出排名靠前的幾個類和物件。這些都是後面要重點進行分析的物件。

2)每隔一定時間段生成一次MAT分析報告,對比這幾次報告,在在Histogram和Dominator Tree檢視中找出Retailed Heap不斷增大的幾個類和物件。持續佔用記憶體,還不釋放,通常意味著有潛在的記憶體洩露問題。

3)當然,如果一個物件的Retained Size很大,並不一定代表它一定是有問題的,還需要具體情況具體分析。具體來說,我們可以分析一個物件到根物件的引用路徑來分析為什麼該物件不能被順利回收。如果說一個物件已經不被任何程式邏輯所需要,但是還存在被根物件引用的情況,基本上就可以說這裡存在記憶體洩露的問題。通過Histogram或者Dominator Tree檢視找到疑似有問題的類或者物件之後,選擇Path to GC Roots或者Merge Shortest Paths to GC Roots。這裡有很多過濾選項,一般來講可以選擇exclude all phantom/weak/soft etc.references。這樣就排除了虛引用、弱引用、以及軟引用,剩下的就是強引用。除了強引用外,其它任何型別的引用,在Java虛擬機器需要的情況下,都可以被GC釋放掉。如果一個物件始終無法被釋放,肯定是因為有強引用存在。

4)接下來就需要直接定位具體的程式碼,看看如何釋放這些不該存在的物件。找到原因,清理乾淨後,再對照之前的操作,看看物件是否任然持續增長。如果不再,則說明這個潛在的記憶體洩露問題已經被修復了。

相關推薦

Eclipse使用MAT分析Android程式記憶體使用狀況()

對於Android這種手持裝置來說,通常不會帶有太大的記憶體,而且一般使用者都是長時間不重啟手機,所以編寫程式的時候必須要非常小心的使用記憶體,儘量避免有記憶體洩露的問題出現。通常分析程式中潛在記憶體洩露的問題是一件很有難度的工作,一般都是由團隊中的資深工程師負責,而且隨著程式程式碼量的提高,難度還會逐步加大

MAT分析android記憶體洩漏

轉載請標明出處:https://www.cnblogs.com/tangZH/p/10955429.html   洩漏,洩漏,漏~ 記憶體洩漏怎麼破,什麼是記憶體洩漏?與記憶體溢位有什麼區別?   記憶體洩漏(Memory Leak):是指程式中己動態分配的堆記憶體由於某種原因程

使用IDA_Pro分析Android程式

使用IDA_Pro分析Android程式 (作者:Baron_wu 禁止轉載) 首先安裝IDA_Pro(安裝方法自行查閱) 之後將apk應用字尾改為zip,然後解壓,開啟IDA_Pro進入空的工作臺,將解壓後的資料夾內的classes.dex拖入工作臺中,之後便開始分析程式。 在使

使用apktool分析Android程式

使用apktool分析Android程式 (作者:Baron_wu 禁止轉載) Installation for Apktool •Windows: 1. Download Windows wrapper script (Right click, Save Lin

eclipse中用bluestack執行android程式

1、安裝bluestack,下載地址http://www.bluestacks.cn/ 2、開啟eclipse,進入DDMS介面,如下圖。 3、eclipse會識別到bluestack,如果沒有識別到的話,可通過下圖的reset adb操作。 4、執行程式,右鍵run&nbs

OpenCVMatAndroidBitmap簡介

        因為在介紹這部分系列的內容時,預設是對Android開發有一點基礎的,所以這樣的話,Bitmap可能就相對很熟悉了,相較陌生的是Mat,那我們就首先來看看Mat是什麼。 1,Mat 1.1 Mat基本介紹 Mat是OpenCV中用於

使用jmap和MAT分析JVM堆記憶體

我的一臺生產環境機器每次執行幾天之後就會莫名其妙的宕機,分析日誌之後發現在tomcat剛啟動的時候記憶體佔用比較少,但是執行個幾天之後記憶體佔用越來越大,通過jmap命令可以查詢到一些大物件引用沒有被及時GC,這裡就要求解決記憶體洩露的問題。 Java的記憶體洩露多半是因為

當從別處匯入新的專案到.eclipse 時. 解決Android studio模擬器開啟黑屏。

解決Android studio模擬器開啟黑屏。   注意下圖。    選 擇software或hardware都可以。不選用預設的automatic =============================================

利用Android Studio、MATAndroid進行記憶體洩漏檢測

專案進入維護階段時才有時間測試分析app的記憶體問題,這時就要用到測試工具了,可以使用Android Studio、MAT互相結合進行測試, 但是對於複雜的,這兩者很難分析出來,但這兩測試工具也是必須掌握的,感覺網上大多文章講得不怎麼細緻,所以想寫篇文章記錄下,剛好看到本文

【Bugly乾貨分享】手把手教你逆向分析 Android 程式

很多人寫文章,喜歡把什麼行業現狀啊,研究現狀啊什麼的寫了一大通,感覺好像在寫畢業論文似的,我這不廢話,先直接上幾個圖,感受一下。 第一張圖是在把程式碼注入到地圖裡面,啟動首頁的時候彈出個浮窗,下載網路的圖片,蒼老師你們不會不認識吧? 第二張圖是微信運動步

循序漸進學用MAT排查Android Activity記憶體洩露

一、先磨刀再砍柴,記憶體洩露相關介紹   我們先來簡單重溫一下Java GC 的概念:GC即為Garbage Collection,垃圾回收機制。Java GC實質上也就是一個執行在Java虛擬機器(JVM)上的一個程式,它自動地管理著記憶體的使用,在適當的時

jstat命令分析java程式記憶體回收情況

命令格式: jstat -gc <pid> <period> <times> 示例: 結果中每個專案的含義可以參考官方對jstat的文件,簡單翻譯如下: - S0C: Young Generation第一個survivor spac

Eclipse啟動Tomcat,設定記憶體

-Xms128M -Xmx512M -XX:PermSize=64M -XX:MaxPermSize=128M -Xms128m JVM初始分配的堆記憶體 -Xmx512m JVM最大允許分配的堆記憶

圖解eclipse執行C語言程式

現在上課講C語言的課,因為非常不喜歡VC++,聽說eclipse也可以做C的程式,就找了一下配置方法。 首先要有以下三樣東西: ①JDK1.5,因為eclipse執行環境需要,呵,沒辦法 ②eclipse+CDT外掛,我是直接在官方網站上下載的帶有CDT外掛的eclipse,

脫離資料線,使用Eclipse通過WIFI除錯Android程式

如需轉載請標明出處:http://blog.csdn.net/itas109 QQ技術交流群:129518033  更新電腦端版本為v1.1    2014-02-20 優化連線,介面做了修改

eclipse 使用MAT分析堆疊

1. 介紹 Eclipse MAT是eclipse提供的外掛用於分析JAVA heap。試過很多分析heap的,但是沒有比這個

eclipsesvn圖標詳解(

tin note 引用 pda call use ips linked Opens - 已忽略版本控制的文件。可以通過Window → Preferences → Team → Ignored Resources.來忽略文件。A file ignored by versio

利用WinDbg分析C#程式產生的儲檔案

 何志丹 啟動對應版本(X86,X64)的WinDbg,主選單“File->Open Crash dump”開啟崩潰轉儲檔案。假定崩潰的程式是Eholly。依次執行以下4命令。 ld Eholly sxe ld:clrjit .loadby sos clr !dum

利用VC/VS檢測程式記憶體溢位()

VisualC++沒有預設啟動記憶體洩露檢測,即如果某段程式碼產生記憶體溢位也不會在“輸出視窗”除錯標籤下輸出記憶體溢位相關資訊 (1)需要手工新增程式碼檢測#define _CRTDBG_MAP_ALLOC//順序改變後 函式可能無法正常工作 #include <s

使用Valgrind找出AndroidNative程式記憶體洩露問題

轉自 https://blog.csdn.net/roland_sun/article/details/46049485   Android程式通常使用Java程式編寫,由於Dalvik虛擬機器集成了垃圾回收機制,所以記憶體使用比較不容易出錯,通常就是一個本該被釋放的物件