性能優(yōu)化工具(八)-MAT

一拭荤、簡介

MAT是Memory Analyzer tool的縮寫,是一種快速纠俭,功能豐富的Java堆分析工具沿量,能幫助你查找內(nèi)存泄漏和減少內(nèi)存消耗。很多情況下冤荆,我們需要處理測試提供的hprof文件朴则,分析內(nèi)存相關(guān)問題,那么MAT也絕對是不二之選钓简。 Eclipse可以下載插件結(jié)合使用乌妒,也可以作為一個(gè)獨(dú)立分析工具使用,下載地址:MAT

二外邓、獲取hprof文件

我們先了解如何獲取hprof文件
在AS monitor 的 memory部分撤蚊,進(jìn)行如下操作:

左邊欄選擇Captures,在Heap Snapshot文件夾內(nèi)會(huì)生成對應(yīng)的hprof文件损话,再轉(zhuǎn)化為可供MAT使用的標(biāo)準(zhǔn)hprof文件侦啸,操作如下:

如果不用MAT槽唾,那么不需要轉(zhuǎn)為標(biāo)準(zhǔn)hprof文件,在右邊部門就能看到分析報(bào)表光涂,可以進(jìn)行對應(yīng)分析庞萍。但是建議還是使用MAT工具分析,功能更加全面些忘闻。

三钝计、MAT工具使用介紹

如何下載和安裝這里就不講了,自行百度或者google齐佳。

用工具打開標(biāo)準(zhǔn).hprof文件后界面如下:

我們主要分析Actions, 它包含了4個(gè)部分:

視圖 含義
histogram 列舉內(nèi)存中對象存在的個(gè)數(shù)和大小
Dominator tree 該視圖會(huì)以占用總內(nèi)存的百分比來列舉所有實(shí)例對象私恬,注意這個(gè)地方是對象而不是類了,這個(gè)視圖是用來發(fā)現(xiàn)大內(nèi)存對象的
Top Consumers 該視圖會(huì)顯示可能的內(nèi)存泄漏點(diǎn)
Duplicate Classes 該視圖顯示重復(fù)的類等信息

點(diǎn)擊他們能得到不同的視圖炼吴,下面來一一介紹:
3.1 Histogram:

點(diǎn)擊Histogram之后本鸣,會(huì)出現(xiàn)如下界面:


這個(gè)視圖中提供了多種方式來對對象進(jìn)行分類,這里為了分析方便硅蹦,我們選擇按包名進(jìn)行分類永高。

下面再來解釋下列名:

列名 含義
Object 該類在內(nèi)存當(dāng)中的對象個(gè)數(shù)
Shallow Heap 對象自身所占用的內(nèi)存大小,不包括它所引用的對象的內(nèi)存大小
Retained Heap 該對象被垃圾回收器回收之后提针,會(huì)釋放的內(nèi)存大小

我們再來看一下右鍵菜單選項(xiàng):

1)List objects:


with outgoing references: 查看它所引用的對象
with incoming references: 查看它被哪些對象引用

2)Show objects by class
和List objects選項(xiàng)類似命爬,只不過列出的是類名。

3)Merge Shortest Paths to GC Roots
我們可以選擇排除一些類型的引用:

3.2 Dominator Tree:

通過“引用樹”的方式來展現(xiàn)內(nèi)存的使用情況的辐脖,通俗點(diǎn)來說饲宛,它是站在對象的角度來觀察內(nèi)存的使用情況的,主要看是否存在異常的大內(nèi)存對象

3.3 Top consumersDuplicate Classes: 不常用嗜价,讀者可以自行使用下

四艇抠、簡單案例分析

案例:將Activity的實(shí)例被一個(gè)單例對象所持有,在旋轉(zhuǎn)屏幕的時(shí)候造成內(nèi)存泄漏

public class CommonUtils {
    private static CommonUtils instance;
    private Context context;
    private CommonUtils(Context context){
        this.context = context;
    }

    public static CommonUtils getInstance(Context context){
        if(instance == null){
            instance = new CommonUtils(context);
        }
        return instance;
    }
}
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        CommonUtils.getInstance(this);//單例模式內(nèi)存泄漏
    }
}

4.1生成hprof文件并導(dǎo)入MAT

生成過程不贅述了,2份hprof文件 一份是沒有旋轉(zhuǎn)過屏幕的久锥, 一份是旋轉(zhuǎn)過屏幕多次的家淤,用來做泄漏和無泄漏的對比,幫助定位問題瑟由。

打開MAT 導(dǎo)入我們的2個(gè)hprof文件 Open File-->選擇文件-->Leak Suspects Report-->Finish

4.2生成比較結(jié)果表

兩個(gè)文件都分別先點(diǎn)擊Action中histogram視圖絮重,然后打開下面的面板Navigation History ,會(huì)發(fā)現(xiàn)有兩個(gè)histogram歹苦,分別選中histogram右鍵add to Compare Basket 添加到比較容器中青伤。

添加到比較容器,然后進(jìn)行比較:

比較之后生成Compared Tables:

然后通過合理的懷疑和猜測殴瘦,且通過對比狠角,找出有問題的類。當(dāng)然蚪腋,這個(gè)列子很簡單丰歌,而且位置也很清楚姨蟋,但是較為復(fù)雜的項(xiàng)目,這一步就是體力活了立帖。只能耐著性子一點(diǎn)點(diǎn)分析比較芬探。

定位到hasMemLeak.hprof存在內(nèi)存泄漏:

下一步,找到hasMemLeak.hprof對應(yīng)的histogram, 再去觀察MainActivtiy具體被哪些對象引用:

看到MainActivty被引用的地方這么多 而且一屏還顯示不完 我們又如何去判斷是哪個(gè)導(dǎo)致內(nèi)存泄漏的呢 MAT還有一個(gè)功能 就是通過遍歷GC Root樹去將那些有可能被GC回收的實(shí)例 將他們?nèi)コ▊渥ⅲ涸贕C Root樹中能找到的對象絕對不存在有內(nèi)存泄漏的實(shí)例 因?yàn)樗麄冊谶\(yùn)行時(shí)會(huì)被回收的嘛 只有找不到的那些才是:

排除虛引用厘惦、弱引用、軟引用哩簿,之后剩余的才是有分析價(jià)值的:

找到問題然后去修改代碼:

CommUtil instance = CommUtil.getInstance(getApplicationContext());

之后再抓hprof測試修改

分析總結(jié):
通過操作宵蕉,觀察android monitor的內(nèi)存變化,在橫豎屏切換或者頁面進(jìn)入退出之后节榜,內(nèi)存在短時(shí)間沒有明顯回落的羡玛,都是內(nèi)存泄漏的懷疑點(diǎn)。確認(rèn)幾個(gè)合理的懷疑范圍之后宗苍,通過抓取對比的hprof文件稼稿,先定位到泄漏的類,然后再通過分析它引用了誰或者誰引用了它來定位最終問題讳窟。同時(shí)可以通過排除虛引用让歼、弱引用、軟引用等等GC可以回收的引用來縮小分析范圍丽啡。

不得不承認(rèn)谋右,MAT分析內(nèi)存問題,還是比較麻煩的补箍,如果想圖方便的話改执,下期會(huì)講一個(gè)傻瓜式工具:LeakCanary.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者坑雅。
  • 序言:七十年代末辈挂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子裹粤,更是在濱河造成了極大的恐慌终蒂,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遥诉,死亡現(xiàn)場離奇詭異后豫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)突那,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門挫酿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人愕难,你說我怎么就攤上這事早龟”拱裕” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵葱弟,是天一觀的道長壹店。 經(jīng)常有香客問我,道長芝加,這世上最難降的妖魔是什么硅卢? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮藏杖,結(jié)果婚禮上将塑,老公的妹妹穿的比我還像新娘。我一直安慰自己蝌麸,他們只是感情好点寥,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著来吩,像睡著了一般敢辩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上弟疆,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天戚长,我揣著相機(jī)與錄音,去河邊找鬼怠苔。 笑死历葛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嘀略。 我是一名探鬼主播恤溶,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼帜羊!你這毒婦竟也來了咒程?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤讼育,失蹤者是張志新(化名)和其女友劉穎帐姻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體奶段,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饥瓷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了痹籍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片呢铆。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蹲缠,靈堂內(nèi)的尸體忽然破棺而出棺克,到底是詐尸還是另有隱情悠垛,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布娜谊,位于F島的核電站确买,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纱皆。R本人自食惡果不足惜湾趾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望派草。 院中可真熱鬧搀缠,春花似錦、人聲如沸澳眷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钳踊。三九已至,卻和暖如春勿侯,著一層夾襖步出監(jiān)牢的瞬間拓瞪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工助琐, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祭埂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓兵钮,卻偏偏與公主長得像蛆橡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子掘譬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345