1.打開Memory Profiler窗口
? 首先你的手機得連接到電腦豺裆;點擊android profiler工具打開圖像化界面如下圖:
選擇你需要觀測的進程:
2.Memory Profiler窗口介紹
Android Profiler中包含如下的分析組件,個人覺得3.0后的android studio提供的這個工具,比之前的android monitor工具好用了很多沸呐,它包含了断部,CPUProfiler(應(yīng)用線程 cpu占用分析) ,
Memory Profiler(內(nèi)存分析),NETWORKProfiler(流量分析),ENERGYProfiler(電量分析),目前只關(guān)注了內(nèi)存的分析朵你,其他幾項后續(xù)持續(xù)調(diào)研并添加探赫;
一個完整的Memory Profiler窗口如下:
A:代表當前app的狀態(tài),比如當前正在ServiceOptionActivity頁面撬呢,藍色代表正在當前運行的界面伦吠,如果是灰色這代表已經(jīng)離開當前頁面,可以用來觀測acitivity的跳轉(zhuǎn)魂拦;
B:幾種內(nèi)存類型介紹:
Java :?java代碼分配的內(nèi)存毛仪;
Native?:?c/c++代碼分配的內(nèi)存(有時候其實并沒有使用到c/c++代碼,但還是會有Native的內(nèi)存分配,因為Android Framework會去通過java代碼訪問一些需要使用Native的資源芯勘,如圖像資源Bitmap)箱靴;
Graphics?:?圖像緩存等,包括GL surfaces, GL textures等荷愕;
Stack?:?應(yīng)用中的原生堆棧和 Java 堆棧使用的內(nèi)存衡怀。 這通常與您的應(yīng)用運行多少線程有關(guān);
Code?:?您的應(yīng)用用于處理代碼和資源(如 dex 字節(jié)碼安疗、已優(yōu)化或已編譯的 dex 碼抛杨、.so 庫和字體)的內(nèi)存;
Other?:?系統(tǒng)不知道是什么類型的內(nèi)存荐类,放在這里怖现;
Allocated?:?應(yīng)用分配的 Java/Kotlin 對象數(shù)。 它沒有計入 C 或 C++ 中分配的對象;
C:是android profiler提供的一些工具選擇:
如+屈嗤,-用于放大縮小界面潘拨,或者暫停或者重新開始檢測饶号;
D:當選擇了某一個切面铁追,dump了一個hprof文件進行分析的時候,就會使用到這里的選擇茫船,
前一個選擇項選擇heap類型
App heap:應(yīng)用在其中分配內(nèi)存的主堆脂信;
Image heap:系統(tǒng)啟動映像,包含啟動期間預(yù)加載的類透硝。 此處的分配保證絕不會移動或消失狰闪;
Zygote heap:寫時復制堆,其中的應(yīng)用進程是從 Android 系統(tǒng)中派生的濒生;
后一個選擇項控制數(shù)據(jù)的排列方式:
Arrange by class:基于類名稱對所有分配進行分組埋泵;
Arrange by package:基于軟件包名稱對所有分配進行分組;
Arrange by callstack:將所有分配分組到其對應(yīng)的調(diào)用堆棧罪治。 此選項僅在記錄分配期間捕獲堆轉(zhuǎn)儲時才有效。即使如此觉义,堆中的對象也很可能是在您開始記錄之前分配的,
因此這些分配會首先顯示霉撵,且只按類名稱列出;
E:?應(yīng)用分配的 Java/Kotlin 對象數(shù)洪囤;
F:?應(yīng)用分配的Native占用的空間徒坡;
G:?當前實例的大小喇完;
H:?此實例支配的內(nèi)存大小,包括了該實例直接或者間接應(yīng)用到的其他對象锦溪,也就是說該對象被GC掉了后,對于的這些內(nèi)存也會被回收府怯;
I:正在分析的hprof文件刻诊,你實際dump的內(nèi)存數(shù)據(jù),注意為了保持數(shù)據(jù)的準確性富腊,在每次dump前需要手動觸發(fā)幾次GC這樣保證這里的數(shù)據(jù)確實存在引用鏈導致數(shù)據(jù)無法被回收域帐;
J:?用于觸發(fā)GC是整,已經(jīng)切換觀測項,可以在這里切換去觀測其他性能數(shù)據(jù)浮入,在dump數(shù)據(jù)前需要點擊手動觸發(fā)GC;
3.分析出現(xiàn)內(nèi)存泄漏的方式:
比如現(xiàn)在我已經(jīng)關(guān)閉了某一個activity頁面羊异,這個時候我手動觸發(fā)了幾次GC,然后dump一個內(nèi)存hprof文件野舶,但是,發(fā)現(xiàn)當前的activity還在內(nèi)存中平道,并且占有了很多內(nèi)存空間,就說明存在該界面內(nèi)存泄漏
如下圖窘疮,我們找到我們的程序包名,然后查看這些對象存在是否合理:
如果你發(fā)現(xiàn)一個類存在問題闸衫,假設(shè)如下圖:
可以點擊Jump to source跳轉(zhuǎn)至源碼進行具體分析诽嘉,也可以在instance view中觀測改對象的一些引用鏈信息,便于我們分析對象哪里被持有了導致不能被GC身冬;