Android Studio:利用 Profiler 來監(jiān)控 CPU豺谈、內(nèi)存和網(wǎng)絡(luò)

本教程相當(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)程,如下圖所示吐根。

Android Profiler 窗口

上圖中各個(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 概覽

如上圖所示铺厨,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)程(如 JDWPProfile Saver褐捻、Studio:VMStats掸茅、Studio:Perfa 以及 Studio:Heartbeat)的線程 CPU 使用率椅邓。

2.2 記錄和檢查函數(shù)跟蹤

選擇 SampledInstrumented ,然后點(diǎn)擊Record開始記錄函數(shù)跟蹤昧狮,點(diǎn)擊Stop recording結(jié)束景馁,如下圖所示。

記錄和檢查函數(shù)跟蹤

① 選擇時(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í)間的概念讯泣。

使用 Call Chart 標(biāo)簽檢查跟蹤

提示: 若要跳轉(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)。

使用 Flame Chart 標(biāo)簽檢查跟蹤

由于 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(好大啊,誰(shuí)能教我怎么縮圖逻谦?)

如上圖所示掌实,在“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(好大啊分苇,誰(shuí)能教我怎么縮圖添诉?)

如上圖所示,在“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ì)話框,如下圖所示棒呛。

創(chuàng)建記錄配置

可以在左側(cè)窗格中選擇現(xiàn)有配置來檢查其設(shè)置聂示,也可按如下方式創(chuàng)建一個(gè)新的記錄配置:

1. 點(diǎn)擊對(duì)話框左上角的 ? 。

2. 為配置命名簇秒。

3. 在 Trace Technology 部分選擇 SampledInstrumented鱼喉。

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 概覽

如上圖所示,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í)間線下,顯示堆中的所有類類型猛遍,如下圖所示馋记。

堆轉(zhuǎn)儲(chǔ)

要檢查堆,請(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)生泄漏的代碼谒养。

分析內(nèi)存泄漏示例(艾瑪挺狰,真的好大。蝴光。她渴。)

首先,我們可以反復(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)存泄漏的代碼,如下:

產(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 概覽

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ù)


參考

  1. https://developer.android.com/studio/profile/android-profiler
  2. https://blog.csdn.net/niubitianping/article/details/72617864
  3. https://blog.csdn.net/Double2hao/article/details/78784758
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蝴韭,隨后出現(xiàn)的幾起案子够颠,更是在濱河造成了極大的恐慌,老刑警劉巖榄鉴,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件履磨,死亡現(xiàn)場(chǎng)離奇詭異蛉抓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)剃诅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門巷送,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人矛辕,你說我怎么就攤上這事笑跛。” “怎么了聊品?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵堡牡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我杨刨,道長(zhǎng),這世上最難降的妖魔是什么擦剑? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任妖胀,我火速辦了婚禮,結(jié)果婚禮上惠勒,老公的妹妹穿的比我還像新娘赚抡。我一直安慰自己,他們只是感情好纠屋,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布涂臣。 她就那樣靜靜地躺著,像睡著了一般售担。 火紅的嫁衣襯著肌膚如雪赁遗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天族铆,我揣著相機(jī)與錄音岩四,去河邊找鬼。 笑死哥攘,一個(gè)胖子當(dāng)著我的面吹牛剖煌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播逝淹,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼耕姊,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了栅葡?” 一聲冷哼從身側(cè)響起茉兰,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎妥畏,沒想到半個(gè)月后邦邦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體安吁,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年燃辖,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鬼店。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡黔龟,死狀恐怖妇智,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情氏身,我是刑警寧澤巍棱,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站蛋欣,受9級(jí)特大地震影響航徙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜陷虎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一到踏、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尚猿,春花似錦窝稿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至庄萎,卻和暖如春踪少,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背惨恭。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工秉馏, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人脱羡。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓萝究,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锉罐。 傳聞我的和親對(duì)象是個(gè)殘疾皇子帆竹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容