背景
前幾天寫了一篇文章關(guān)于Android幾種常見(jiàn)的內(nèi)存泄漏問(wèn)題和解決方法,還沒(méi)看的朋友也可以先看一下。那么當(dāng)我們真正遇到不知道問(wèn)題的內(nèi)存泄漏的時(shí)候該怎么去分析和檢測(cè)它呢?
內(nèi)存泄漏檢測(cè)工具
利用MAT來(lái)分析內(nèi)存泄漏
首先我們就拿一個(gè)最簡(jiǎn)單的內(nèi)存泄漏的例子來(lái)分析一下
public class MainActivity extends Activity {
private static Context sContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sContext = this;
}
}
1.首先我們手動(dòng)出發(fā)一下GC然后查看Dump

突然發(fā)現(xiàn)最新的AndroidStudio沒(méi)有上面的了,也有可能是我沒(méi)找到,但是在tools里面有Monitors,打開(kāi)是下面的界面,也可以導(dǎo)出hprof文件

導(dǎo)出之后的文件是不能直接被MAT識(shí)別的需要通過(guò)hprof-conv命令來(lái)轉(zhuǎn)換一下,這個(gè)是Android SDK提供的工具,在plafrom-tools目錄下
hprof-conv com.aotuman.leak.hprof(原文件) com.aotuman.leak.hprof(輸出文件)
然年后我們就可以利用MAT來(lái)打開(kāi)文件進(jìn)行內(nèi)存分析了:

從圖我們可看到MAT提供了很多功能,但是最常用的只有Histogran和Dominator Tree.
Histogran:可以直觀的看出內(nèi)存中不同類型的buffer的數(shù)量和占用的內(nèi)存大小
Dominator Tree:把內(nèi)存中的對(duì)象按照從大到小的順序進(jìn)行排序,并且可以分析對(duì)象之間的引用關(guān)系,內(nèi)存泄漏分析就是通過(guò)他來(lái)實(shí)現(xiàn)的
下面兩張圖就是他倆的界面:


那么我們到底應(yīng)該怎么來(lái)查看內(nèi)存泄漏呢,比如我們的Demo我們大概知道是MainActivity產(chǎn)生了內(nèi)存泄漏,我們可以搜索,然后按照下圖的方式來(lái)查看他的引用(在Histogram和Dominator_Tree兩個(gè)界面都可以這么去查看引用關(guān)系):

查看完之后我們就會(huì)看到這個(gè)界面:

從圖中我們就可以看到,是因?yàn)閟Context導(dǎo)致了內(nèi)存泄漏。
利用LeakCanary來(lái)查看內(nèi)存泄漏
這種方式比較簡(jiǎn)單和直觀,有內(nèi)存泄漏的時(shí)候他會(huì)之間提示你造成內(nèi)存泄漏的引用鏈。
使用方法也很簡(jiǎn)單:

下面是發(fā)生內(nèi)存泄漏之后,手機(jī)上的提示,它會(huì)彈出在通知欄。

是不是很簡(jiǎn)單明了,不需要我們自己去分析和查找,只要你是期間出現(xiàn)內(nèi)存泄漏它都會(huì)提示給你。
當(dāng)然如果有想深入研究的同學(xué)可以去Google一下,查看它的源碼,分析一下實(shí)現(xiàn)原理,這里就不展開(kāi)了。
總結(jié)
以上是我常用的兩種方法,如果大家有其他更好的可以留言告訴樓主,我也可以學(xué)習(xí)一下,總的來(lái)說(shuō)內(nèi)存泄漏是一個(gè)相對(duì)較為復(fù)雜的問(wèn)題,但是只要我們掌握了一定的技巧那么解決起來(lái)也是很簡(jiǎn)單的。