本教程相當(dāng)于官方教程的精簡(jiǎn)版覆旱,將官方教程的干貨提取出來。另外還寫了一個(gè)分析內(nèi)存泄漏的例子核无。
Android Profiler能夠提供關(guān)于應(yīng)用 CPU扣唱、內(nèi)存和網(wǎng)絡(luò)的實(shí)時(shí)數(shù)據(jù)。
1 啟動(dòng)分析
要打開 Android Profiler 窗口团南,請(qǐng)按以下步驟操作:
1. 點(diǎn)擊工具欄中的 Android Profiler(也可以點(diǎn)擊 View > Tool Windows > Android Profiler )噪沙。
2. 在 Android Profiler 窗口頂部選擇想要分析的設(shè)備和應(yīng)用進(jìn)程,如下圖所示吐根。
上圖中各個(gè)數(shù)字對(duì)應(yīng)的含義:
① 要分析的設(shè)備正歼。
② 要分析的應(yīng)用進(jìn)程。
③ 時(shí)間線縮放控件拷橘。
④ 實(shí)時(shí)更新跳轉(zhuǎn)按鈕局义。
⑤ Event時(shí)間線,包括Activity狀態(tài)冗疮、用戶輸入Event和屏幕旋轉(zhuǎn)Event萄唇。
如果顯示“Advanced profiling is unavailable for the selected process”,可以在頂層工具欄中點(diǎn)擊 Profile 'app' 來運(yùn)行术幔,或者在運(yùn)行配置中啟用高級(jí)分析另萤,按以下步驟操作:
1. 選擇 Run > Edit Configurations。
2. 在左側(cè)窗格中選擇您的應(yīng)用模塊诅挑。
3. 點(diǎn)擊 Profiling 標(biāo)簽四敞,然后勾選 Enable advanced profiling。
重新構(gòu)建并運(yùn)行應(yīng)用即可拔妥。
2 CPU Profiler
CPU Profiler 可幫助實(shí)時(shí)檢查應(yīng)用的 CPU 使用率和線程 Activity忿危,并記錄函數(shù)跟蹤,以便優(yōu)化和調(diào)試應(yīng)用代碼没龙。
2.1 CPU Profiler 概覽
如上圖所示铺厨,CPU Profiler 的默認(rèn)視圖包括以下內(nèi)容:
① Event 時(shí)間線: 顯示應(yīng)用中在其生命周期轉(zhuǎn)換的 Activity,并顯示用戶與設(shè)備的交互兜畸,包括屏幕旋轉(zhuǎn) Event努释。
② CPU 時(shí)間線: 顯示應(yīng)用的實(shí)時(shí) CPU 使用率(占總可用 CPU 時(shí)間的百分比)以及應(yīng)用使用的總線程數(shù)。 此時(shí)間線還顯示其他進(jìn)程的 CPU 使用率(如系統(tǒng)進(jìn)程或其他應(yīng)用)咬摇,以便可以將其與自己的應(yīng)用使用率進(jìn)行對(duì)比伐蒂。 通過沿時(shí)間線的水平軸移動(dòng)鼠標(biāo),還可以檢查歷史 CPU 使用率數(shù)據(jù)肛鹏。
③ 線程 Activity 時(shí)間線: 列出屬于應(yīng)用進(jìn)程的每個(gè)線程逸邦。下面說明不同的顏色對(duì)應(yīng)的含義:
- 綠色: 表示線程處于活動(dòng)狀態(tài)或準(zhǔn)備使用 CPU恩沛。 即,它正在“運(yùn)行中”或處于“可運(yùn)行”狀態(tài)缕减。
- 黃色: 表示線程處于活動(dòng)狀態(tài)雷客,但它正在等待一個(gè) I/O 操作(如磁盤或網(wǎng)絡(luò) I/O),然后才能完成它的工作桥狡。
- 灰色: 表示線程正在休眠且沒有消耗任何 CPU 時(shí)間搅裙。 當(dāng)線程需要訪問尚不可用的資源時(shí)偶爾會(huì)發(fā)生這種情況。 線程進(jìn)入自主休眠或內(nèi)核將此線程置于休眠狀態(tài)裹芝,直到所需的資源可用部逮。
④ 記錄配置: 選擇分析器記錄函數(shù)跟蹤的方式,如下:
- Sampled: 以固定周期記錄嫂易。在應(yīng)用執(zhí)行期間頻繁捕獲應(yīng)用的調(diào)用堆棧兄朋。 分析器比較捕獲的數(shù)據(jù)集以推導(dǎo)與應(yīng)用代碼執(zhí)行有關(guān)的時(shí)間和資源使用信息。 基于“Sampled”的跟蹤的問題是怜械,如果應(yīng)用在捕獲調(diào)用堆棧后進(jìn)入一個(gè)函數(shù)并在下一次捕獲前退出該函數(shù)颅和,則分析器不會(huì)記錄該函數(shù)調(diào)用。 如果對(duì)此類生命周期很短的跟蹤函數(shù)感興趣缕允,應(yīng)使用“Instrumented”跟蹤峡扩。
- Instrumented: 以函數(shù)調(diào)用時(shí)間為周期記錄。在運(yùn)行時(shí)設(shè)置應(yīng)用以在每個(gè)函數(shù)調(diào)用的開始和結(jié)束時(shí)記錄時(shí)間戳灼芭。 它收集時(shí)間戳并進(jìn)行比較有额,以生成函數(shù)跟蹤數(shù)據(jù),包括時(shí)間信息和 CPU 使用率彼绷。 注意,與設(shè)置每個(gè)函數(shù)關(guān)聯(lián)的開銷會(huì)影響運(yùn)行時(shí)性能茴迁,并可能會(huì)影響分析數(shù)據(jù)寄悯,對(duì)于生命周期相對(duì)較短的函數(shù),這一點(diǎn)更為明顯堕义。 此外猜旬,如果應(yīng)用短時(shí)間內(nèi)執(zhí)行大量函數(shù),則分析器可能會(huì)迅速超出它的文件大小限制倦卖,且不能再記錄更多的跟蹤數(shù)據(jù)洒擦。
- Edit configurations: 允許更改上述“Sampled”和“Instrumented”記錄配置的某些默認(rèn)值,并將它們另存為自定義配置怕膛。
⑤ 記錄按鈕: 用于開始和停止記錄函數(shù)跟蹤熟嫩。
注: 分析器還會(huì)報(bào)告 Android Studio 和 Android 平臺(tái)添加到您的應(yīng)用進(jìn)程(如 JDWP、Profile Saver褐捻、Studio:VMStats掸茅、Studio:Perfa 以及 Studio:Heartbeat)的線程 CPU 使用率椅邓。
2.2 記錄和檢查函數(shù)跟蹤
選擇 Sampled 或 Instrumented ,然后點(diǎn)擊Record開始記錄函數(shù)跟蹤昧狮,點(diǎn)擊Stop recording結(jié)束景馁,如下圖所示。
① 選擇時(shí)間范圍: 確定要在跟蹤窗格中檢查所記錄時(shí)間范圍的哪一部分逗鸣。 當(dāng)首次記錄函數(shù)跟蹤時(shí)合住,CPU Profiler 將在 CPU 時(shí)間線中自動(dòng)選擇完整長(zhǎng)度。 如果想僅檢查所記錄時(shí)間范圍一小部分的函數(shù)跟蹤數(shù)據(jù)撒璧,可以點(diǎn)擊并拖動(dòng)突出顯示的區(qū)域邊緣以修改其長(zhǎng)度透葛。
② 時(shí)間戳: 用于表示所記錄函數(shù)跟蹤的開始和結(jié)束時(shí)間(相對(duì)于分析器從設(shè)備開始收集 CPU 使用率信息的時(shí)間)。 可以點(diǎn)擊時(shí)間戳以自動(dòng)選擇完整記錄沪悲。
③ 跟蹤窗格: 用于顯示所選的時(shí)間范圍和線程的函數(shù)跟蹤數(shù)據(jù)获洲。
④ 通過調(diào)用圖表、火焰圖殿如、 Top Down 樹或Bottom Up 樹的形式顯示函數(shù)跟蹤贡珊。
⑤ 確定如何測(cè)量每個(gè)函數(shù)調(diào)用的時(shí)間信息:
- Wall clock time:實(shí)際經(jīng)過的時(shí)間。
- Thread time:實(shí)際經(jīng)過的時(shí)間減去線程沒有消耗 CPU 資源的時(shí)間涉馁。
2.2.1 使用 Call Chart 標(biāo)簽檢查跟蹤
Call Chart 標(biāo)簽提供函數(shù)跟蹤的圖形表示形式门岔,其中,水平軸表示函數(shù)調(diào)用(或調(diào)用方)的時(shí)間烤送,并沿垂直軸顯示其被調(diào)用者寒随。 對(duì)系統(tǒng) API 的函數(shù)調(diào)用顯示為橙色,對(duì)應(yīng)用自有函數(shù)的調(diào)用顯示為綠色帮坚,對(duì)第三方 API(包括 Java 語(yǔ)言 API)的函數(shù)調(diào)用顯示為藍(lán)色妻往。 下圖展示了一個(gè)調(diào)用圖表示例,并描繪了給定函數(shù)的 Self time试和、Children time 以及總時(shí)間的概念讯泣。
提示: 若要跳轉(zhuǎn)到某個(gè)函數(shù)的源代碼,請(qǐng)右鍵點(diǎn)擊該函數(shù)并選擇 Jump to Source阅悍。
2.2.2 使用 Flame Chart 標(biāo)簽檢查跟蹤
Flame Chart 標(biāo)簽提供一個(gè)倒置的調(diào)用圖表好渠,其中水平軸不再代表時(shí)間線,它表示每個(gè)函數(shù)相對(duì)的執(zhí)行時(shí)間节视。
下面說明此概念拳锚,考慮下圖中的調(diào)用圖表。注意函數(shù) D 多次調(diào)用 B(B1寻行、B2 和 B3)霍掺,其中一些對(duì) B 的調(diào)用也調(diào)用了 C(C1 和 C3)。
由于 B1、B2 和 B3 共享相同的調(diào)用方順序 (A → D → B)抗楔,因此可將它們匯總在一起棋凳,如下所示。 同樣连躏,將 C1 和 C3 匯總在一起剩岳,因?yàn)樗鼈円补蚕硐嗤恼{(diào)用方順序 (A → D → B → C)。注意未包含 C2入热,因?yàn)樗哂胁煌恼{(diào)用方順序 (A → D → C)拍棕。
匯總的函數(shù)調(diào)用用于創(chuàng)建火焰圖,如下圖所示勺良。注意绰播,對(duì)于火焰圖中任何給定的函數(shù)調(diào)用,首先顯示消耗最多 CPU 時(shí)間的被調(diào)用方尚困。
2.2.3 使用 Top Down 和 Bottom Up 檢查跟蹤
Top Down 標(biāo)簽顯示一個(gè)函數(shù)調(diào)用列表蠢箩,在該列表中展開函數(shù)節(jié)點(diǎn)會(huì)顯示函數(shù)的被調(diào)用方。 下圖顯示上面調(diào)用圖表對(duì)應(yīng)的“Top Down”圖表事甜。圖表中的每個(gè)箭頭都從調(diào)用方指向被調(diào)用方谬泌。
如上圖所示掌实,在“Top Down”標(biāo)簽中展開函數(shù) A 的節(jié)點(diǎn)可顯示它的被調(diào)用方,即函數(shù) B 和 D邦马。 然后贱鼻,展開函數(shù) D 的節(jié)點(diǎn)可顯示它的被調(diào)用方,即函數(shù) B 和 C 等等滋将。
Top Down 標(biāo)簽提供以下信息以說明在每個(gè)函數(shù)調(diào)用上所花費(fèi)的 CPU 時(shí)間:
- Self: 表示函數(shù)調(diào)用在執(zhí)行自己的代碼(而非被調(diào)用方的代碼)上所花的時(shí)間邻悬。
- Children: 表示函數(shù)調(diào)用在執(zhí)行自己的被調(diào)用方(而非自己的代碼)上所花的時(shí)間。
- 總和: 函數(shù)的 Self 和 Children 時(shí)間的總和随闽。 表示應(yīng)用在執(zhí)行函數(shù)調(diào)用上所花的總時(shí)間拘悦。
Bottom Up 標(biāo)簽顯示一個(gè)函數(shù)調(diào)用列表,在該列表中展開函數(shù)節(jié)點(diǎn)將顯示函數(shù)的調(diào)用方橱脸,如下圖所示。
如上圖所示,在“Bottom Up”樹中打開函數(shù) C 的節(jié)點(diǎn)可顯示它的調(diào)用方 B 和 D医寿。 注意栏赴,盡管 B 調(diào)用 C 兩次滤愕,但在“Bottom Up”樹中展開函數(shù) C 的節(jié)點(diǎn)時(shí)葡粒,B 僅顯示一次腮敌。 然后鸣剪,展開 B 的節(jié)點(diǎn)顯示其調(diào)用方,即函數(shù) A 和 D花颗。
注:當(dāng)分析器到達(dá)文件大小限制時(shí)捕传,Android Studio 將停止收集新數(shù)據(jù)(但不會(huì)停止記錄)。
2.3 創(chuàng)建記錄配置
要?jiǎng)?chuàng)建或編輯自定義配置扩劝,或檢查現(xiàn)有的默認(rèn)配置庸论,可通過記錄配置下拉菜單中選擇 Edit configurations 來打開 CPU Recording Configurations 對(duì)話框,如下圖所示棒呛。
可以在左側(cè)窗格中選擇現(xiàn)有配置來檢查其設(shè)置聂示,也可按如下方式創(chuàng)建一個(gè)新的記錄配置:
1. 點(diǎn)擊對(duì)話框左上角的 ? 。
2. 為配置命名簇秒。
3. 在 Trace Technology 部分選擇 Sampled 或 Instrumented鱼喉。
4. 對(duì)于“Sampled”記錄配置,以微秒 (μs) 為單位指定 Sampling interval趋观。 此值表示應(yīng)用調(diào)用堆棧的每個(gè)抽樣之間的持續(xù)時(shí)間扛禽。
5. 對(duì)于寫入連接設(shè)備的記錄數(shù)據(jù),以兆字節(jié) (MB) 為單位指定 File size limit拆内。 當(dāng)您停止記錄時(shí)旋圆,Android Studio 將解析此數(shù)據(jù)并將其顯示在分析器窗口中。
注: 如果使用運(yùn)行 API 級(jí)別 26 或更高版本的連接設(shè)備麸恍,則對(duì)于跟蹤數(shù)據(jù)的文件大小沒有限制灵巧,此值可忽略。
6. 點(diǎn)擊 Apply 或 OK抹沪。 如果更改了其他記錄配置刻肄,則也將保存這些更改。
3 Memory Profiler
Memory Profiler 是可幫助識(shí)別導(dǎo)致應(yīng)用卡頓融欧、凍結(jié)甚至崩潰的內(nèi)存泄漏和流失敏弃。 它顯示一個(gè)應(yīng)用內(nèi)存使用量的實(shí)時(shí)圖表,可以捕獲堆轉(zhuǎn)儲(chǔ)噪馏、強(qiáng)制執(zhí)行垃圾回收以及跟蹤內(nèi)存分配麦到。
3.1 Memory Profiler 概覽
如上圖所示,Memory Profiler 的默認(rèn)視圖包括以下各項(xiàng):
① 強(qiáng)制執(zhí)行垃圾回收 Event 欠肾。
② 捕獲堆轉(zhuǎn)儲(chǔ)瓶颠。
③ 記錄內(nèi)存分配情況。 此按鈕僅在運(yùn)行 Android 7.1 或更低版本的設(shè)備時(shí)才會(huì)顯示刺桃。
④ 放大/縮小時(shí)間線粹淋。
⑤ 跳轉(zhuǎn)至實(shí)時(shí)內(nèi)存數(shù)據(jù)。
⑥ Event 時(shí)間線,其顯示 Activity 狀態(tài)桃移、用戶輸入 Event 和屏幕旋轉(zhuǎn) Event屋匕。
⑦ 內(nèi)存使用量時(shí)間線,包含以下內(nèi)容:
- 顯示每個(gè)內(nèi)存類別使用多少內(nèi)存的堆疊圖表借杰,如左側(cè)的 y 軸以及頂部的彩色鍵所示过吻。
- 虛線表示分配的對(duì)象數(shù),如右側(cè)的 y 軸所示第步。
- 用于表示每個(gè)垃圾回收 Event 的圖標(biāo)疮装。
如上圖,內(nèi)存計(jì)數(shù)中的類別如下所示:
- Java:從 Java 或 Kotlin 代碼分配的對(duì)象內(nèi)存粘都。
- Native:從 C 或 C++ 代碼分配的對(duì)象內(nèi)存廓推。
- Graphics:圖形緩沖區(qū)隊(duì)列向屏幕顯示像素(包括 GL 表面、GL 紋理等等)所使用的內(nèi)存翩隧。 (注意樊展,這是與 CPU 共享的內(nèi)存,不是 GPU 專用內(nèi)存堆生。)
- Stack: 應(yīng)用中的原生堆棧和 Java 堆棧使用的內(nèi)存专缠,通常與應(yīng)用運(yùn)行多少線程有關(guān)。
- Code:應(yīng)用用于處理代碼和資源(如 dex 字節(jié)碼淑仆、已優(yōu)化或已編譯的 dex 碼涝婉、.so 庫(kù)和字體)的內(nèi)存。
- Other:應(yīng)用使用的系統(tǒng)不確定如何分類的內(nèi)存蔗怠。
- Allocated:應(yīng)用分配的 Java/Kotlin 對(duì)象數(shù)墩弯。 沒有計(jì)入 C 或 C++ 中分配的對(duì)象。
注:目前寞射,Memory Profiler 還會(huì)顯示應(yīng)用中的一些誤報(bào)的原生內(nèi)存使用量渔工,而這些內(nèi)存實(shí)際上是分析工具使用的。 對(duì)于大約 100000 個(gè)對(duì)象桥温,最多會(huì)使報(bào)告的內(nèi)存使用量增加 10MB引矩。
3.2 查看內(nèi)存分配
Memory Profiler 可顯示有關(guān)對(duì)象分配的以下信息:
- 分配哪些類型的對(duì)象以及它們使用多少空間。
- 每個(gè)分配的堆疊追蹤侵浸,包括在哪個(gè)線程中旺韭。
- 對(duì)象在何時(shí)被取消分配(Android 8.0+)。
如果設(shè)備運(yùn)行 Android 8.0 或更高版本掏觉,可以按照下述方法查看對(duì)象分配: 只需點(diǎn)擊并按住時(shí)間線茂翔,并拖動(dòng)選擇想要查看分配的區(qū)域,如下圖所示:
如果設(shè)備運(yùn)行 Android 7.1 或更低版本履腋,則在 Memory Profiler 工具欄中點(diǎn)擊 Record memory allocations 。 操作完成后,點(diǎn)擊 Stop recording 以查看分配遵湖。如下圖所示:
在選擇一個(gè)時(shí)間線區(qū)域后悔政,已分配對(duì)象的列表將顯示在時(shí)間線下方,按類名稱進(jìn)行分組延旧,并按其堆計(jì)數(shù)排序谋国。
注:在 Android 7.1 及更低版本上,最多可以記錄 65535 個(gè)分配迁沫。 如果記錄超出此限值芦瘾,則記錄中僅保存最新的 65535 個(gè)分配。 在 Android 8.0 及更高版本中集畅,沒有此限制近弟。
要檢查分配記錄,請(qǐng)按以下步驟操作:
1. 瀏覽列表以查找堆計(jì)數(shù)異常大且可能存在泄漏的對(duì)象挺智。 點(diǎn)擊 Class Name 列標(biāo)題可以按字母順序排序祷愉。 然后點(diǎn)擊一個(gè)類名稱。 此時(shí)在右側(cè)將出現(xiàn) Instance View 窗格赦颇,顯示該類的每個(gè)實(shí)例二鳄。
2. 在 Instance View 窗格中,點(diǎn)擊一個(gè)實(shí)例媒怯。 此時(shí)下方將出現(xiàn) Call Stack 標(biāo)簽订讼,顯示該實(shí)例被分配到何處以及在哪個(gè)線程中,如下圖所示扇苞。
3. 在 Call Stack 標(biāo)簽中欺殿,雙擊任意行以在編輯器中跳轉(zhuǎn)到該代碼。
默認(rèn)情況下杨拐,左側(cè)的分配列表按類名稱排列祈餐。 在列表頂部,可以使用右側(cè)的下拉列表在以下排列方式之間進(jìn)行切換:
- Arrange by class:基于類名稱對(duì)所有分配進(jìn)行分組哄陶。
- Arrange by package:基于軟件包名稱對(duì)所有分配進(jìn)行分組帆阳。
- Arrange by callstack:將所有分配分組到其對(duì)應(yīng)的調(diào)用堆棧。
3.3 捕獲堆轉(zhuǎn)儲(chǔ)
堆轉(zhuǎn)儲(chǔ)顯示在捕獲堆轉(zhuǎn)儲(chǔ)時(shí)應(yīng)用中哪些對(duì)象正在使用內(nèi)存屋吨。 特別是在長(zhǎng)時(shí)間的用戶會(huì)話后蜒谤,堆轉(zhuǎn)儲(chǔ)會(huì)顯示您認(rèn)為不應(yīng)再位于內(nèi)存中卻仍在內(nèi)存中的對(duì)象,從而幫助識(shí)別內(nèi)存泄漏至扰。 在捕獲堆轉(zhuǎn)儲(chǔ)后鳍徽,可以查看以下信息:
- 應(yīng)用已分配哪些類型的對(duì)象,以及每個(gè)類型分配多少敢课。
- 每個(gè)對(duì)象正在使用多少內(nèi)存阶祭。
- 在代碼中的何處仍在引用每個(gè)對(duì)象绷杜。
- 對(duì)象所分配到的調(diào)用堆棧。 (目前濒募,如果在記錄分配時(shí)捕獲堆轉(zhuǎn)儲(chǔ)鞭盟,則只有在 Android 7.1 及更低版本中,堆轉(zhuǎn)儲(chǔ)才能使用調(diào)用堆棧瑰剃。)
要捕獲堆轉(zhuǎn)儲(chǔ)齿诉,在 Memory Profiler 工具欄中點(diǎn)擊 Dump Java heap 。 在轉(zhuǎn)儲(chǔ)堆期間晌姚,Java 內(nèi)存量可能會(huì)暫時(shí)增加粤剧, 這很正常,因?yàn)槎艳D(zhuǎn)儲(chǔ)與您的應(yīng)用發(fā)生在同一進(jìn)程中挥唠,并需要一些內(nèi)存來收集數(shù)據(jù)抵恋。
堆轉(zhuǎn)儲(chǔ)顯示在內(nèi)存時(shí)間線下,顯示堆中的所有類類型猛遍,如下圖所示馋记。
要檢查堆,請(qǐng)按以下步驟操作:
1. 瀏覽列表以查找堆計(jì)數(shù)異常大且可能存在泄漏的對(duì)象懊烤。 點(diǎn)擊 Class Name 列標(biāo)題可以按字母順序排序梯醒。 然后點(diǎn)擊一個(gè)類名稱。 此時(shí)在右側(cè)將出現(xiàn) Instance View 窗格腌紧,顯示該類的每個(gè)實(shí)例茸习。
2. 在 Instance View 窗格中,點(diǎn)擊一個(gè)實(shí)例壁肋,此時(shí)下方將出現(xiàn) References号胚,顯示該對(duì)象的每個(gè)引用。點(diǎn)擊實(shí)例名稱旁的箭頭可以查看其所有字段浸遗,然后點(diǎn)擊一個(gè)字段名稱查看其所有引用猫胁。 如果要查看某個(gè)字段的實(shí)例詳情,右鍵點(diǎn)擊該字段并選擇 Go to Instance跛锌,如下圖所示弃秆。
3. 在 References 標(biāo)簽中,如果發(fā)現(xiàn)某個(gè)引用可能在泄漏內(nèi)存髓帽,則右鍵點(diǎn)擊它并選擇 Go to Instance菠赚。
在類列表中,可以查看以下信息:
- Heap Count:堆中的實(shí)例數(shù)郑藏。
- Shallow Size:此堆中所有實(shí)例的總大泻獠椤(以字節(jié)為單位)。
- Retained Size:為此類的所有實(shí)例而保留的內(nèi)存總大斜馗恰(以字節(jié)為單位)拌牲。
在類列表頂部俱饿,可以使用左側(cè)下拉列表在以下堆轉(zhuǎn)儲(chǔ)之間進(jìn)行切換:
- Default heap:系統(tǒng)未指定堆時(shí)。
- App heap:應(yīng)用在其中分配內(nèi)存的主堆们拙。
- Image heap:系統(tǒng)啟動(dòng)映像稍途,包含啟動(dòng)期間預(yù)加載的類。 此處的分配保證絕不會(huì)移動(dòng)或消失砚婆。
- Zygote heap:寫時(shí)復(fù)制堆,其中的應(yīng)用進(jìn)程是從 Android 系統(tǒng)中派生的突勇。
默認(rèn)情況下装盯,此列表按 Retained Size 列排序,可以點(diǎn)擊任意列標(biāo)題以更改列表的排序方式甲馋。
在 Instance View 中埂奈,每個(gè)實(shí)例都包含以下信息:
- Depth:從任意 GC root 到所選實(shí)例的最短 hop 數(shù)。
- Shallow Size:此實(shí)例的大小定躏。
- Retained Size:此實(shí)例支配的內(nèi)存大小账磺。
3.4 將堆轉(zhuǎn)儲(chǔ)另存為 HPROF
如果要保存堆轉(zhuǎn)儲(chǔ)以供日后查看,可通過點(diǎn)擊時(shí)間線下方工具欄中的 Export heap dump as HPROF file痊远,將堆轉(zhuǎn)儲(chǔ)導(dǎo)出到一個(gè) HPROF 文件中垮抗。 在顯示的對(duì)話框中,確保使用 .hprof 后綴保存文件碧聪。然后冒版,通過將此文件拖到一個(gè)空的編輯器窗口就可以在 Android Studio 中打開該文件。
要使用其他 HPROF 分析器(如 jhat)逞姿,需要將 HPROF 文件從 Android 格式轉(zhuǎn)換為 Java SE HPROF 格式辞嗡。 可以使用 android_sdk/platform-tools/ 目錄中的 hprof-conv 工具執(zhí)行此操作。 運(yùn)行該命令需要兩個(gè)參數(shù):原始 HPROF 文件和轉(zhuǎn)換后 HPROF 文件的寫入位置滞造。 例如:
hprof-conv heap-original.hprof heap-converted.hprof
3.5 分析內(nèi)存泄漏示例
下面舉例說明如何分析內(nèi)存泄漏续室。
下圖點(diǎn)擊中間可以進(jìn)入一個(gè)產(chǎn)生內(nèi)存泄漏的Activity,下面展示如何通過Memory Profiler找到產(chǎn)生內(nèi)存泄漏的類并定位到產(chǎn)生泄漏的代碼谒养。
首先,我們可以反復(fù)進(jìn)入和退出內(nèi)存泄漏Activity蔑祟,然后在Memory Profiler中強(qiáng)制垃圾回收趁耗,之后捕獲堆轉(zhuǎn)儲(chǔ)。待分析結(jié)果出來后疆虚,可以點(diǎn)擊右側(cè)的篩選按鈕苛败,篩選我們關(guān)注的包名满葛,如下圖所示:
也可以在“Arrange by class”處選擇“Arrange by package”來進(jìn)行手動(dòng)選擇。
可以看到有3個(gè)MemoryLeakActivity對(duì)象罢屈,按理說退出它們并GC之后不應(yīng)該在內(nèi)存中嘀韧。我們單擊那一行,右側(cè)會(huì)顯示每個(gè)實(shí)例缠捌,點(diǎn)擊其中一個(gè)實(shí)例锄贷,下面會(huì)顯示其引用,如下圖所示:
我們可以雙擊第一個(gè)引用曼月,或者右鍵點(diǎn)擊選擇“Jump to Source”谊却,就可以定位到產(chǎn)生內(nèi)存泄漏的代碼,如下:
這樣一個(gè)內(nèi)存泄漏的分析過程就結(jié)束了哑芹。
4 Network Profiler
Network Profiler 能夠在時(shí)間線上顯示實(shí)時(shí)網(wǎng)絡(luò) Activity炎辨,包括發(fā)送和接收的數(shù)據(jù)以及當(dāng)前的連接數(shù),便于查看應(yīng)用傳輸數(shù)據(jù)的方式和時(shí)間聪姿,并據(jù)此對(duì)底層代碼進(jìn)行適當(dāng)優(yōu)化碴萧。
4.1 Network Profiler 概覽
如上圖所示,窗口頂部顯示的是 Event 時(shí)間線以及無(wú)線裝置功耗狀態(tài)(低/高)與 WLAN 的對(duì)比①末购。 在時(shí)間線上破喻,可以點(diǎn)擊并拖動(dòng)選擇時(shí)間線的一部分來檢查網(wǎng)絡(luò)流量②。 下方的窗口③會(huì)顯示在時(shí)間線的選定片段內(nèi)收發(fā)的文件招盲,包括文件名稱低缩、大小、類型曹货、狀態(tài)和時(shí)間咆繁。 可以點(diǎn)擊任意列標(biāo)題排序。 同時(shí)顶籽,還可以查看時(shí)間線選定片段的明細(xì)數(shù)據(jù)玩般,顯示每個(gè)文件的發(fā)送和接收時(shí)間。
點(diǎn)擊網(wǎng)絡(luò)連接的名稱即可查看有關(guān)所發(fā)送或接收的選定文件的詳細(xì)信息④礼饱。 點(diǎn)擊各個(gè)標(biāo)簽可查看響應(yīng)數(shù)據(jù)坏为、標(biāo)題信息和調(diào)用堆棧。
注:Network Profiler 目前只支持 HttpURLConnection 和 OkHttp 網(wǎng)絡(luò)連接庫(kù)镊绪。
Google 官方出了一個(gè)新的介紹文章匀伏,可以參考學(xué)習(xí):使用 Android Studio Profiler 工具解析應(yīng)用的內(nèi)存和 CPU 使用數(shù)據(jù)