Android性能優(yōu)化--內(nèi)存優(yōu)化(2)

Performance Optimization
接下來(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)始分析
  1. 首先可以通過(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)行.png
       3.旋轉(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)存泄露的情況。
  1. 由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)分感謝!!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容