
接下來(lái)一段時(shí)間會(huì)持續(xù)更新“性能優(yōu)化”專(zhuān)題中有關(guān)于Android方面的文章,敬請(qǐng)關(guān)注!
Android性能優(yōu)化--內(nèi)存優(yōu)化(1)
上一篇文章中提到了如何使用Android Studio來(lái)查找分析內(nèi)存泄露,今天結(jié)合MAT繼續(xù)分析。
現(xiàn)在我們依據(jù)下面的一個(gè)內(nèi)存泄漏的示例代碼逐步進(jìn)行分析。
1. 內(nèi)存泄漏示例代碼
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
}
private void initData() {
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
//do something
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
}
修改方案:將非靜態(tài)內(nèi)部類(lèi)修改為靜態(tài)內(nèi)部類(lèi)(靜態(tài)內(nèi)部類(lèi)不會(huì)隱士持有外部類(lèi))。
private void initData() ------> private static void initData()
2. 今天分析會(huì)結(jié)合MAT,所以先準(zhǔn)備好工具。
MAT下載地址:MAT下載 (自己根據(jù)自己的電腦配置自行選擇)
3. 以上面的內(nèi)存泄露示例開(kāi)始分析
-
首先可以通過(guò)Android Studio的Memoey Usage查看程序的Activities和Views的數(shù)量情況。
這里做一個(gè)對(duì)比,比較修改前后Activities和Views的數(shù)量情況,對(duì)比步驟:
1. Memory Usage入口
MemoryUsage.png
2. 修改前后都正常運(yùn)行應(yīng)用,可以看到下圖
正常運(yùn)行.png3.旋轉(zhuǎn)屏幕四次,然后退出應(yīng)用,并且在AS上手動(dòng)GC,再查看數(shù)量修改前:
修改之前的.png修改后:
修改之后的.png
從這里可以看出來(lái),修改前后Activities的數(shù)量有明顯的不同,
正常來(lái)說(shuō),手動(dòng)GC之后,應(yīng)該為0,所以可以推測(cè)存在內(nèi)存泄露的情況。
-
由Android Studio生成.hprof文件,在MAT中進(jìn)行分析。
1.AS也可以分析hprof文件(上篇文字中有提到,這里再?gòu)?fù)習(xí)一下)
AS中的分析結(jié)果.png
2. 找到AS生成的.hprof文件,導(dǎo)出保存(AS點(diǎn)擊Dump Java Heap會(huì)生成hprof文件)
AS中文件導(dǎo)出的位置.png
3. 將保存的文件導(dǎo)入MAT,會(huì)看到下圖,然后選擇Overview,下方再選擇Histogram,會(huì)出現(xiàn)一個(gè)列表
導(dǎo)入文件后按步驟進(jìn)行操作.png
4.下圖中我們可以通過(guò)MAT的篩選功能找到我們需要的內(nèi)容,可以通過(guò)包名或者類(lèi)名篩選
Histogram列表.png
5.按照我們上面的示例,篩選之后就出現(xiàn)下圖的結(jié)果,然后我們繼續(xù)往下分析,
截圖看不到的步驟這里用文字表述:
選中一行,右鍵 ---> List objects ---> with incoming reference,(incoming 表示被引用,outgoing表示引用了誰(shuí))
被引用列表.png
6. 從上面篩選之后可以看到7個(gè)MainActivity的引用,我們要去除一些不必關(guān)注的引用內(nèi)容,比如弱引用、軟引用等,截圖看不到的步驟如下:
選中一行,右鍵 ---> Path To GC Roots ---> exclude all phantom/weak/soft etc. references
incoming篩選后的列表.png
7. 可以看到,通過(guò)篩選之后,最終看到了我們示例中非靜態(tài)內(nèi)部類(lèi)對(duì)外部類(lèi)的引用
最終篩選結(jié)果.png
4.總結(jié)
這篇文章主要是利用AS結(jié)合MAT對(duì)內(nèi)存泄露的情況進(jìn)行分析,MAT中還有可以根據(jù)包名進(jìn)行篩選等功能大家可以摸索嘗試,文中有不足或者錯(cuò)誤之處還望大神們賜教,萬(wàn)分感謝!!










