CPU Profiler

Start

優(yōu)化應(yīng)用的 CPU 使用率具有許多優(yōu)勢(shì)括细,如提供更快且更順暢的用戶體驗(yàn)膘格,以及延長(zhǎng)設(shè)備電池續(xù)航時(shí)間忿峻。

您可以使用 CPU Profiler 在與應(yīng)用交互時(shí)實(shí)時(shí)檢查應(yīng)用的 CPU 使用率和線程活動(dòng)群发,也可以檢查記錄的方法跟蹤數(shù)據(jù)、函數(shù)跟蹤數(shù)據(jù)和系統(tǒng)跟蹤數(shù)據(jù)的詳細(xì)信息惹挟。

  • 系統(tǒng)跟蹤數(shù)據(jù):捕獲精細(xì)的詳細(xì)信息,以便您檢查應(yīng)用與系統(tǒng)資源的交互情況缝驳。
  • 方法和函數(shù)跟蹤數(shù)據(jù):對(duì)于應(yīng)用進(jìn)程中的每個(gè)線程连锯,您可以了解一段時(shí)間內(nèi)執(zhí)行了哪些方法 (Java) 或函數(shù) (C/C++),以及每個(gè)方法或函數(shù)在其執(zhí)行期間消耗的 CPU 資源用狱。您還可以使用方法和函數(shù)跟蹤數(shù)據(jù)來識(shí)別調(diào)用方和被調(diào)用方运怖。調(diào)用方是指調(diào)用其他方法或函數(shù)的方法或函數(shù),而被調(diào)用方是指被其他方法或函數(shù)調(diào)用的方法或函數(shù)夏伊。您可以使用此信息來確定哪些方法或函數(shù)負(fù)責(zé)調(diào)用常常會(huì)消耗大量資源的特定任務(wù)摇展,并優(yōu)化應(yīng)用的代碼以避免不必要的工作。

記錄方法跟蹤數(shù)據(jù)時(shí)溺忧,您可以選擇 “sampled” 或 “instrumented” 記錄吗购。記錄函數(shù)跟蹤數(shù)據(jù)時(shí)医男,只能使用 “sampled” 記錄。

CPU Profiler 概覽

要打開 CPU Profiler捻勉,請(qǐng)按以下步驟操作:

  1. 依次選擇 View > Tool Windows > Profiler镀梭,或點(diǎn)擊工具欄中的 Profile 圖標(biāo)

如果 Select Deployment Target 對(duì)話框提示,請(qǐng)選擇要將您的應(yīng)用部署到哪個(gè)設(shè)備上以進(jìn)行分析踱启。如果您已通過 USB 連接設(shè)備但系統(tǒng)未列出該設(shè)備报账,請(qǐng)確保您已啟用 USB 調(diào)試。

  1. 點(diǎn)擊 CPU 時(shí)間軸上的任意位置以打開 CPU Profiler埠偿。

當(dāng)您打開 CPU Profiler 時(shí)透罢,它會(huì)立即開始顯示應(yīng)用的 CPU 使用率和線程活動(dòng)。您應(yīng)該會(huì)看到類似于圖 1 的一些內(nèi)容冠蒋。


圖 1. CPU Profiler 中的時(shí)間軸

如圖 1 所示羽圃,CPU Profiler 的默認(rèn)視圖包括以下時(shí)間軸:

  1. 事件時(shí)間軸:顯示應(yīng)用中的 Activity 在其生命周期內(nèi)不斷轉(zhuǎn)換而經(jīng)歷各種不同狀態(tài)的過程,并指示用戶與設(shè)備的交互抖剿,包括屏幕旋轉(zhuǎn)事件朽寞。如需了解如何在搭載 Android 7.1(API 級(jí)別 25)及更低版本的設(shè)備上啟用事件時(shí)間軸,請(qǐng)參閱啟用高級(jí)分析斩郎。

  2. CPU 時(shí)間軸:顯示應(yīng)用的實(shí)時(shí) CPU 使用率(以占總可用 CPU 時(shí)間的百分比表示)以及應(yīng)用當(dāng)前使用的線程總數(shù)脑融。此時(shí)間軸還顯示其他進(jìn)程(如系統(tǒng)進(jìn)程或其他應(yīng)用)的 CPU 使用率,以便您可以將其與您應(yīng)用的使用率進(jìn)行對(duì)比缩宜。您可以通過沿時(shí)間軸的水平軸移動(dòng)鼠標(biāo)來檢查歷史 CPU 使用率數(shù)據(jù)肘迎。

  3. 線程活動(dòng)時(shí)間軸:列出屬于應(yīng)用進(jìn)程的每個(gè)線程,并使用下面列出的顏色在時(shí)間軸上指示它們的活動(dòng)锻煌。記錄跟蹤數(shù)據(jù)后妓布,您可以從此時(shí)間軸上選擇一個(gè)線程,以在跟蹤數(shù)據(jù)窗格中檢查其數(shù)據(jù)宋梧。

    • 綠色:表示線程處于活動(dòng)狀態(tài)或準(zhǔn)備使用 CPU秋茫。也就是說,它處于正在運(yùn)行或可運(yùn)行狀態(tài)乃秀。
    • 黃色:表示線程處于活動(dòng)狀態(tài)肛著,但它正在等待一項(xiàng) I/O 操作(如磁盤或網(wǎng)絡(luò) I/O),然后才能完成它的工作跺讯。
    • 灰色:表示線程正在休眠且沒有消耗任何 CPU 時(shí)間枢贿。當(dāng)線程需要訪問尚不可用的資源時(shí),有時(shí)會(huì)發(fā)生這種情況刀脏。在這種情況下局荚,要么線程自主進(jìn)入休眠狀態(tài),要么內(nèi)核將線程置于休眠狀態(tài),直到所需的資源可用耀态。

    CPU Profiler 還會(huì)報(bào)告 Android Studio 和 Android 平臺(tái)添加到應(yīng)用進(jìn)程的線程的 CPU 使用率轮傍,這些線程包括 JDWP、Profile Saver首装、Studio:VMStats创夜、Studio:Perfa 和 Studio:Heartbeat 等(然而,它們?cè)诰€程活動(dòng)時(shí)間軸上顯示的確切名稱可能有所不同)仙逻。Android Studio 將報(bào)告此數(shù)據(jù)驰吓,以便您確定線程活動(dòng)和 CPU 使用率實(shí)際在何時(shí)是由您的應(yīng)用的代碼引發(fā)。

記錄跟蹤數(shù)據(jù)

要開始記錄跟蹤數(shù)據(jù)系奉,請(qǐng)從 CPU Profiler 頂部的下拉菜單中 選擇記錄配置檬贰,然后點(diǎn)擊 Record

圖 2. CPU Profiler 顯示了正在進(jìn)行的記錄的狀態(tài)缺亮、持續(xù)時(shí)間和類型

與您的應(yīng)用交互翁涤,然后在完成時(shí)點(diǎn)擊 Stop。分析器將自動(dòng)選擇記錄的時(shí)間范圍萌踱,并在跟蹤數(shù)據(jù)窗格中顯示其跟蹤信息葵礼,如圖 3 所示。如果要檢查其他線程的跟蹤數(shù)據(jù)虫蝶,請(qǐng)從線程活動(dòng)時(shí)間軸上選擇相應(yīng)線程。

圖 3. 記錄方法跟蹤數(shù)據(jù)后的 CPU Profiler
  1. 選定范圍:確定要在跟蹤數(shù)據(jù)窗格中檢查所記錄時(shí)間的哪一部分倦西。當(dāng)您首次記錄跟蹤數(shù)據(jù)時(shí)能真,CPU Profiler 會(huì)自動(dòng)在 CPU 時(shí)間軸上選擇記錄的完整長(zhǎng)度。要僅檢查所記錄時(shí)間范圍的一部分的跟蹤數(shù)據(jù)扰柠,請(qǐng)拖動(dòng)突出顯示區(qū)域的邊緣粉铐。
  2. 時(shí)間戳:指示所記錄跟蹤數(shù)據(jù)的開始和結(jié)束時(shí)間(相對(duì)于分析器開始收集 CPU 使用率信息的時(shí)間)。要選擇完整的記錄卤档,請(qǐng)點(diǎn)擊時(shí)間戳蝙泼。
  3. 跟蹤數(shù)據(jù)窗格:顯示您選擇的時(shí)間范圍和線程的跟蹤數(shù)據(jù)。只有在您至少記錄一條跟蹤數(shù)據(jù)后劝枣,才會(huì)顯示此窗格汤踏。在此窗格中,您可以選擇如何查看每個(gè)堆棧軌跡(使用跟蹤數(shù)據(jù)標(biāo)簽)舔腾,以及如何測(cè)量執(zhí)行時(shí)間(使用時(shí)間參考下拉菜單)溪胶。
  4. 跟蹤數(shù)據(jù)窗格標(biāo)簽:選擇如何顯示跟蹤數(shù)據(jù)詳細(xì)信息。如需詳細(xì)了解各個(gè)選項(xiàng)稳诚,請(qǐng)參閱 檢查跟蹤數(shù)據(jù)哗脖。
  5. 時(shí)間參考菜單:選擇以下選項(xiàng)之一,以確定如何測(cè)量每次調(diào)用的時(shí)間信息:
    • Wall clock time:時(shí)間信息表示實(shí)際經(jīng)過的時(shí)間。
    • Thread time:時(shí)間信息表示實(shí)際經(jīng)過的時(shí)間減去線程在該時(shí)間內(nèi)沒有消耗 CPU 資源的所有部分才避。對(duì)于任何給定的調(diào)用橱夭,其線程時(shí)間始終小于或等于其掛鐘時(shí)間。使用線程時(shí)間可以讓您更好地了解線程的實(shí)際 CPU 使用率中有多少是給定方法或函數(shù)消耗的桑逝。
  6. 過濾器:按函數(shù)棘劣、方法、類或軟件包名稱過濾跟蹤數(shù)據(jù)肢娘。例如呈础,如果您要快速識(shí)別與特定調(diào)用相關(guān)的跟蹤數(shù)據(jù),請(qǐng)點(diǎn)擊 Filter 圖標(biāo)

    橱健,或按 Ctrl + F 鍵(在 Mac 上而钞,按 Command + F 鍵),然后在搜索字段中輸入相應(yīng)的名稱拘荡。在 Call chartFlame chart 標(biāo)簽中臼节,會(huì)突出顯示包含符合搜索查詢條件的調(diào)用、軟件包或類的調(diào)用堆棧珊皿。在 Top downBottom up 標(biāo)簽中网缝,這些調(diào)用堆棧優(yōu)先于其他跟蹤結(jié)果。您還可以通過勾選搜索字段旁邊的相應(yīng)框來啟用以下選項(xiàng):
    • Regex:要在您的搜索中包含正則表達(dá)式蟋定,請(qǐng)使用此選項(xiàng)粉臊。
    • Match case:如果您的搜索區(qū)分大小寫,請(qǐng)使用此選項(xiàng)驶兜。
選擇記錄配置

在開始記錄跟蹤信息之前扼仲,請(qǐng)為要捕獲的分析信息選擇適當(dāng)?shù)挠涗浥渲茫?/p>

  • Sample Java Methods:在應(yīng)用的 Java 代碼執(zhí)行期間,頻繁捕獲應(yīng)用的調(diào)用堆棧抄淑。分析器會(huì)比較捕獲的數(shù)據(jù)集屠凶,以推導(dǎo)與應(yīng)用的 Java 代碼執(zhí)行有關(guān)的時(shí)間和資源使用信息。
    基于采樣的跟蹤存在一個(gè)固有的問題肆资,那就是如果應(yīng)用在捕獲調(diào)用堆棧后進(jìn)入一個(gè)方法且在下次捕獲前退出該方法矗愧,則分析器不會(huì)記錄該方法調(diào)用。如果您想要跟蹤生命周期如此短的方法郑原,應(yīng)使用檢測(cè)跟蹤唉韭。

  • Trace Java Methods:在運(yùn)行時(shí)檢測(cè)應(yīng)用,以在每個(gè)方法調(diào)用開始和結(jié)束時(shí)記錄一個(gè)時(shí)間戳犯犁。系統(tǒng)會(huì)收集并比較這些時(shí)間戳纽哥,以生成方法跟蹤數(shù)據(jù),包括時(shí)間信息和 CPU 使用率栖秕。
    請(qǐng)注意春塌,與檢測(cè)每個(gè)方法關(guān)聯(lián)的開銷會(huì)影響運(yùn)行時(shí)性能,并且可能會(huì)影響分析數(shù)據(jù);對(duì)于生命周期相對(duì)較短的方法只壳,這一點(diǎn)更為明顯俏拱。此外,如果應(yīng)用在短時(shí)間內(nèi)執(zhí)行大量方法吼句,則分析器可能很快就會(huì)超出其文件大小限制锅必,因而不能再記錄更多跟蹤數(shù)據(jù)。

  • Trace System Calls:捕獲精細(xì)的詳細(xì)信息惕艳,以便您檢查應(yīng)用與系統(tǒng)資源的交互情況搞隐。您可以檢查線程狀態(tài)的確切時(shí)間和持續(xù)時(shí)間、直觀地查看所有核心的 CPU 瓶頸在何處远搪,并添加要分析的自定義跟蹤事件劣纲。當(dāng)您排查性能問題時(shí),此類信息至關(guān)重要谁鳍。要使用此配置癞季,您必須將應(yīng)用部署到搭載 Android 8.0(API 級(jí)別 26)或更高版本的設(shè)備上。

    使用此跟蹤配置時(shí)倘潜,您可以通過檢測(cè)代碼來直觀地標(biāo)記分析器時(shí)間軸上的重要代碼例程绷柒。要檢測(cè) C/C++ 代碼,請(qǐng)使用 trace.h 提供的原生跟蹤 API涮因。要檢測(cè) Java 代碼废睦,請(qǐng)使用 Trace 類。如需了解詳情养泡,請(qǐng)參閱 檢測(cè)您的應(yīng)用代碼嗜湃。

在搭載 Android 9(API 級(jí)別 28)或更高版本的設(shè)備上,您可以使用一個(gè)名為“系統(tǒng)跟蹤”的系統(tǒng)應(yīng)用來 記錄設(shè)備上的系統(tǒng)跟蹤數(shù)據(jù)瓤荔。

創(chuàng)建净蚤、修改或查看記錄配置

您可以在 CPU Recording Configurations 對(duì)話框中創(chuàng)建钥组、修改和查看記錄配置输硝,從 CPU Profiler 頂部的記錄配置下拉菜單中選擇 Edit configurations 即可打開該對(duì)話框。

要查看某個(gè)現(xiàn)有記錄配置的設(shè)置程梦,請(qǐng)?jiān)?CPU Recording Configurations 對(duì)話框的左側(cè)窗格中選擇該配置点把。

要?jiǎng)?chuàng)建一個(gè)新的記錄配置,請(qǐng)執(zhí)行以下操作:

  1. 點(diǎn)擊對(duì)話框左上角的 Add 圖標(biāo)
    屿附。這樣將創(chuàng)建一個(gè)包含一些默認(rèn)設(shè)置的新配置郎逃。
  2. 為您的配置命名。
  3. 選擇一個(gè) Trace Technology挺份。
  4. 對(duì)于采樣記錄配置褒翰,以微秒 (μs) 為單位指定 Sampling interval。此值表示應(yīng)用的每個(gè)調(diào)用堆棧樣本的時(shí)間間隔。指定的時(shí)間間隔越短优训,達(dá)到記錄數(shù)據(jù)的文件大小限制就越快朵你。
  5. 對(duì)于寫入連接設(shè)備的記錄數(shù)據(jù),以兆字節(jié) (MB) 為單位指定 File size limit揣非。當(dāng)您停止記錄時(shí)抡医,Android Studio 會(huì)解析此數(shù)據(jù)并將其顯示在分析器窗口中。因此早敬,如果您增大此限制并記錄大量的數(shù)據(jù)忌傻,Android Studio 解析文件所需的時(shí)間會(huì)大大增加,并且可能會(huì)變得無響應(yīng)搞监。

注意:如果您使用的連接設(shè)備搭載的是 Android 8.0(API 級(jí)別 26)或更高版本水孩,那么對(duì)跟蹤數(shù)據(jù)的文件大小沒有限制,系統(tǒng)會(huì)忽略此值腺逛。不過荷愕,您仍需留意每次記錄后設(shè)備收集了多少數(shù)據(jù),Android Studio 可能難以解析大型跟蹤文件棍矛。例如安疗,如果您記錄的是采樣時(shí)間間隔很短的采樣跟蹤數(shù)據(jù),或是在應(yīng)用短時(shí)間內(nèi)調(diào)用許多方法的情況下記錄檢測(cè)跟蹤數(shù)據(jù)够委,那么很快就會(huì)生成大型跟蹤文件荐类。

  1. 要接受所做的更改并繼續(xù)對(duì)其他配置進(jìn)行更改,請(qǐng)點(diǎn)擊 Apply茁帽。要接受應(yīng)用的所有更改并關(guān)閉對(duì)話框玉罐,請(qǐng)點(diǎn)擊 OK。
使用 Debug API 記錄 CPU 活動(dòng)

您可以使用 Debug` API 讓您的應(yīng)用能夠在 CPU Profiler 中開始和停止記錄 CPU 活動(dòng)潘拨。

當(dāng)您的應(yīng)用調(diào)用 startMethodTracing(String tracePath) 時(shí)吊输,CPU Profiler 將開始記錄;當(dāng)您的應(yīng)用調(diào)用 stopMethodTracing() 時(shí)铁追,CPU Profiler 將停止記錄季蚂。在記錄使用此 API 觸發(fā)的 CPU 活動(dòng)時(shí),CPU Profiler 會(huì)將 Debug API 顯示為活動(dòng)的 CPU 記錄配置琅束。

在應(yīng)用啟動(dòng)過程中記錄 CPU 活動(dòng)

要在應(yīng)用啟動(dòng)過程中自動(dòng)開始記錄 CPU 活動(dòng)扭屁,請(qǐng)執(zhí)行以下操作:

  1. 依次選擇 Run > Edit Configurations。
  2. 在 Profiling 標(biāo)簽中涩禀,勾選 Start recording a method trace on startup 旁邊的復(fù)選框料滥。
  3. 從菜單中選擇 CPU 記錄配置。
  4. 點(diǎn)擊 Apply艾船。
  5. 依次選擇 Run > Profile,將您的應(yīng)用部署到搭載 Android 8.0(API 級(jí)別 26)或更高版本的設(shè)備上践宴。

導(dǎo)出跟蹤數(shù)據(jù)

使用 CPU Profiler 記錄 CPU 活動(dòng)后,您可以將相應(yīng)數(shù)據(jù)導(dǎo)出為 .trace 文件浴井,以便與他人共享或日后進(jìn)行檢查。

要從 CPU 時(shí)間軸導(dǎo)出跟蹤文件洪囤,請(qǐng)執(zhí)行以下操作:

  1. 在 CPU 時(shí)間軸上,右鍵點(diǎn)擊要導(dǎo)出的記錄的方法跟蹤數(shù)據(jù)或系統(tǒng)跟蹤數(shù)據(jù)撕氧。
  2. 從菜單中選擇** Export trace**瘤缩。
  3. 瀏覽到要將文件保存到的位置剥啤,指定文件名府怯,然后點(diǎn)擊 OK防楷。

要從 Sessions 窗格導(dǎo)出跟蹤文件复局,請(qǐng)執(zhí)行以下操作:

  1. 在 Sessions 窗格中,右鍵點(diǎn)擊要導(dǎo)出的記錄的跟蹤數(shù)據(jù)峦剔。
  2. 點(diǎn)擊會(huì)話條目右側(cè)的 Export method traceExport system trace 按鈕吝沫。
  3. 瀏覽到要將文件保存到的位置野舶,指定文件名宰衙,然后點(diǎn)擊 OK睹欲。

導(dǎo)入跟蹤數(shù)據(jù)

您可以導(dǎo)入使用 Debug API 或 CPU Profiler 創(chuàng)建的 .trace 文件一屋。
要導(dǎo)入跟蹤文件冀墨,請(qǐng)點(diǎn)擊分析器的 Sessions 窗格中的 Start new profiler session 圖標(biāo)

image.png
诽嘉,然后選擇 Load from file虫腋。

您可以檢查 CPU Profiler 中導(dǎo)入的跟蹤數(shù)據(jù)悦冀,就像檢查直接在 CPU Profiler 中捕獲的跟蹤數(shù)據(jù)一樣盒蟆,但有下面幾點(diǎn)不同:

  • CPU 活動(dòng)未顯示在 CPU 時(shí)間軸上师骗。
  • 線程活動(dòng)時(shí)間軸僅指明了可在哪里獲取各線程的跟蹤數(shù)據(jù)辟癌,而未指明實(shí)際線程狀態(tài)(如運(yùn)行中愿待、等待中或休眠中)仍侥。

檢查跟蹤數(shù)據(jù)

CPU Profiler 中的跟蹤數(shù)據(jù)窗格提供多個(gè)標(biāo)簽农渊,供您選擇如何查看所記錄跟蹤數(shù)據(jù)的信息。

對(duì)于方法跟蹤數(shù)據(jù)和函數(shù)跟蹤數(shù)據(jù)传于,您可以從 Call Chart沼溜、Flame Chart系草、Top DownBottom Up 標(biāo)簽中進(jìn)行選擇找都。對(duì)于系統(tǒng)跟蹤數(shù)據(jù)能耻,您可以從 Trace Events、Flame Chart嗡贺、Top DownBottom Up 標(biāo)簽中進(jìn)行選擇诫睬。

使用“Call Chart”標(biāo)簽檢查跟蹤數(shù)據(jù)

Call Chart 標(biāo)簽提供方法跟蹤數(shù)據(jù)或函數(shù)跟蹤數(shù)據(jù)的圖形表示形式摄凡,其中調(diào)用的時(shí)間段和時(shí)間在水平軸上表示亲澡,而其被調(diào)用方顯示在垂直軸上床绪。對(duì)系統(tǒng) API 的調(diào)用顯示為橙色癞己,對(duì)應(yīng)用自有方法的調(diào)用顯示為綠色痹雅,對(duì)第三方 API(包括 Java 語(yǔ)言 API)的調(diào)用顯示為藍(lán)色糊识。圖 4 顯示了一個(gè)調(diào)用圖表示例赂苗,說明了給定方法或函數(shù)的 Self 時(shí)間拌滋、Children 時(shí)間和 Total 時(shí)間的概念鸠真。如需詳細(xì)了解這些概念吠卷,請(qǐng)參閱有關(guān)如何 使用 Top Down 和 Bottom Up 檢查跟蹤數(shù)據(jù)的部分祭隔。

圖 4. 一個(gè)調(diào)用圖表示例疾渴,說明了方法 D 的 Self 時(shí)間搞坝、Children 時(shí)間和 Total 時(shí)間

提示:要跳轉(zhuǎn)到某個(gè)方法或函數(shù)的源代碼桩撮,請(qǐng)右鍵點(diǎn)擊該方法或函數(shù)店量,然后選擇 Jump to Source。從任何跟蹤數(shù)據(jù)窗格標(biāo)簽中均可執(zhí)行此操作右钾。

使用“Flame Chart”標(biāo)簽檢查跟蹤數(shù)據(jù)

Flame Chart 標(biāo)簽提供一個(gè)倒置的調(diào)用圖表舀射,用來匯總完全相同的調(diào)用堆棧后控。也就是說浩淘,將具有相同調(diào)用方順序的完全相同的方法或函數(shù)收集起來张抄,并在 flame 圖中將它們表示為一個(gè)較長(zhǎng)的橫條(而不是將它們顯示為多個(gè)較短的橫條署惯,如調(diào)用圖表中所示)极谊。這樣更方便您查看哪些方法或函數(shù)消耗的時(shí)間最多轻猖。不過咙边,這也意味著,水平軸不代表時(shí)間軸王带,而是表示執(zhí)行每個(gè)方法或函數(shù)所需的相對(duì)時(shí)間量愕撰。

為幫助說明此概念盟戏,不妨考慮圖 5 中的調(diào)用圖表柿究。請(qǐng)注意蝇摸,方法 D 多次調(diào)用 B(B1貌夕、B2 和 B3)啡专,其中一些對(duì) B 的調(diào)用也調(diào)用了 C(C1 和 C3)们童。

圖 5. 一個(gè)調(diào)用圖表慧库,其中的多個(gè)方法調(diào)用有著共同的調(diào)用方順序

由于 B1齐板、B2 和 B3 具有相同的調(diào)用方順序 (A → D → B)甘磨,因此將它們匯總在一起济舆,如圖 6 所示吗冤。同樣椎瘟,也將 C1 和 C3 匯總在一起肺蔚,因?yàn)樗鼈円簿哂邢嗤恼{(diào)用方順序 (A → D → B → C)宣羊。請(qǐng)注意仇冯,C2 不包括在內(nèi)苛坚,因?yàn)樗哂胁煌恼{(diào)用方順序 (A → D → C)泼舱。

圖 6. 匯總具有相同調(diào)用堆棧的完全相同的方法

匯總的調(diào)用用于創(chuàng)建火焰圖,如圖 7 所示冒掌。請(qǐng)注意宋渔,對(duì)于 flame 圖中的任何給定調(diào)用皇拣,先顯示的是消耗最多 CPU 時(shí)間的被調(diào)用方氧急。

圖 7. 圖 5 中所示調(diào)用圖表的flame圖表示形式
使用 "Top Down" 和 "Bottom Up" 檢查跟蹤數(shù)據(jù)

Top Down 標(biāo)簽顯示一個(gè)調(diào)用列表吩坝,在該列表中展開方法或函數(shù)節(jié)點(diǎn)會(huì)顯示它的被調(diào)用方钉寝。圖 8 顯示了圖 4 中調(diào)用圖表的自上而下圖嵌纲。圖中的每個(gè)箭頭都從調(diào)用方指向被調(diào)用方逮走。

如圖 8 所示师溅,在 Top Down 標(biāo)簽中展開方法 A 的節(jié)點(diǎn)會(huì)顯示它的被調(diào)用方墓臭,即方法 B 和 D窿锉。在此之后榆综,展開方法 D 的節(jié)點(diǎn)會(huì)顯示它的被調(diào)用方怯伊,即方法 B 和 C耿芹,依此類推吧秕。與 Flame chart 標(biāo)簽類似砸彬,"Top Down" 樹也匯總具有相同調(diào)用堆棧的完全相同的方法的跟蹤信息砂碉。也就是說增蹭,Flame chart 標(biāo)簽提供 Top down 標(biāo)簽的圖形表示形式滋迈。

Top Down 標(biāo)簽提供以下信息來幫助說明在每個(gè)調(diào)用上所花的 CPU 時(shí)間(時(shí)間也可表示為在選定范圍內(nèi)占線程總時(shí)間的百分比):

  • Self:方法或函數(shù)調(diào)用在執(zhí)行自己的代碼(而非被調(diào)用方的代碼) 上所花的時(shí)間饼灿,如圖 4 中的方法 D 所示赔退。
  • Children:方法或函數(shù)調(diào)用在執(zhí)行它的被調(diào)用方(而非自己的代碼)上所花的時(shí)間硕旗,如圖 4 中的方法 D 所示。
  • Total:方法的 Self 時(shí)間和 Children 時(shí)間的總和墙基。這表示應(yīng)用在執(zhí)行調(diào)用上所花的總時(shí)間残制,如圖 4 中的方法 D 所示初茶。
圖 8. 一個(gè)“Top Down”樹
圖 9. 圖 8 中方法 C 的“Bottom Up”樹

Bottom Up 標(biāo)簽顯示一個(gè)調(diào)用列表,在該列表中展開函數(shù)或方法節(jié)點(diǎn)會(huì)顯示它的調(diào)用方折汞。沿用圖 8 中所示的跟蹤數(shù)據(jù)示例爽待,圖 9 提供了方法 C 的 "Bottom Up" 樹鸟款。在 "Bottom Up" 樹中打開方法 C 的節(jié)點(diǎn)會(huì)顯示它獨(dú)有的各個(gè)調(diào)用方蹄梢,即方法 B 和 D禁炒。請(qǐng)注意幕袱,盡管 B 調(diào)用 C 兩次们豌,但在 "Bottom Up" 樹中展開方法 C 的節(jié)點(diǎn)時(shí)望迎,B 僅顯示一次。在此之后摄欲,展開 B 的節(jié)點(diǎn)會(huì)顯示它的調(diào)用方胸墙,即方法 A 和 D迟隅。

Bottom Up 標(biāo)簽用于按照消耗的 CPU 時(shí)間由多到少(或由少到多)的排序?qū)Ψ椒ɑ蚝瘮?shù)排序玻淑。您可以檢查每個(gè)節(jié)點(diǎn)以確定哪些調(diào)用方在調(diào)用這些方法或函數(shù)上所花的 CPU 時(shí)間最多。與 "Top Down" 樹相比箫锤,"Bottom Up" 樹中每個(gè)方法或函數(shù)的時(shí)間信息參照的是每個(gè)樹頂部的方法(頂部節(jié)點(diǎn))谚攒。CPU 時(shí)間也可表示為在該記錄期間占線程總時(shí)間的百分比馏臭。下表有助于說明如何解釋頂部節(jié)點(diǎn)及其調(diào)用方(子節(jié)點(diǎn))的時(shí)間信息括儒。

Self Children Total
“Bottom Up”樹頂部的方法或函數(shù)(頂部節(jié)點(diǎn)) 表示方法或函數(shù)在執(zhí)行自己的代碼(而非被調(diào)用方的代碼)上所花的總時(shí)間乍狐。與“Top Down”樹相比浅蚪,此時(shí)間信息表示在記錄的持續(xù)時(shí)間內(nèi)對(duì)此方法或函數(shù)的所有調(diào)用的總和惜傲。 表示方法或函數(shù)在執(zhí)行它的被調(diào)用方(而非自己的代碼)上所花的總時(shí)間操漠。與“Top Down”樹相比,此時(shí)間信息表示在記錄的持續(xù)時(shí)間內(nèi)對(duì)此方法或函數(shù)的被調(diào)用方的所有調(diào)用的總和撞秋。 Self 時(shí)間和 Children 時(shí)間的總和长捧。
調(diào)用方(子節(jié)點(diǎn)) 表示被調(diào)用方在由調(diào)用方調(diào)用時(shí)的總 Self 時(shí)間。以圖 9 中的“Bottom Up”樹為例吻贿,方法 B 的 Self 時(shí)間將等于每次執(zhí)行由方法 B 調(diào)用的方法 C 所用的 Self 時(shí)間的總和串结。 表示被調(diào)用方在由調(diào)用方調(diào)用時(shí)的總 Children 時(shí)間。以圖 9 中的“Bottom Up”樹為例舅列,方法 B 的 Children 時(shí)間將等于每次執(zhí)行由方法 B 調(diào)用的方法 C 所用的 Children 時(shí)間的總和。 Self 時(shí)間和 Children 時(shí)間的總和帐要。

注意:對(duì)于給定的記錄把敞,當(dāng)分析器達(dá)到文件大小限制時(shí),Android Studio 會(huì)停止收集新數(shù)據(jù)(不過榨惠,不會(huì)停止記錄)奋早。在執(zhí)行檢測(cè)跟蹤時(shí)盛霎,這種情況通常發(fā)生得更快,因?yàn)榕c采樣跟蹤相比耽装,此類跟蹤會(huì)在更短的時(shí)間內(nèi)收集更多的數(shù)據(jù)愤炸。如果您將檢查時(shí)間范圍延長(zhǎng)至達(dá)到限制后的記錄期間,則跟蹤數(shù)據(jù)窗格中的時(shí)間數(shù)據(jù)不會(huì)發(fā)生變化(因?yàn)闆]有新數(shù)據(jù)可用)掉奄。此外规个,當(dāng)您僅選擇沒有數(shù)據(jù)可用的記錄部分時(shí),對(duì)于時(shí)間信息姓建,跟蹤數(shù)據(jù)窗格將顯示 NaN绰姻。

使用 "Trace Events" 標(biāo)簽檢查系統(tǒng)跟蹤數(shù)據(jù)

檢查系統(tǒng)跟蹤數(shù)據(jù)時(shí),您可以使用 Trace Events 標(biāo)簽查看每個(gè)線程上發(fā)生的事件的詳細(xì)信息引瀑。

要查看某個(gè)線程的詳細(xì)信息狂芋,請(qǐng)?jiān)?Threads 窗格中選擇該線程。這樣將在 Kernel 窗格中突出顯示該線程在每個(gè) CPU 核心上的活動(dòng)憨栽,并在 Trace Events 標(biāo)簽中顯示該線程的事件帜矾。在 Trace Events 標(biāo)簽中將鼠標(biāo)指針懸停在某個(gè)事件上可查看該事件的名稱以及在每種狀態(tài)下所花的時(shí)間。

例如屑柔,在圖 10 中屡萤,在 Threads 窗格中選擇了 RenderThread,在 Kernel 窗格中突出顯示了該線程在 CPU 0 和 CPU 1 上的活動(dòng)掸宛,并在 Trace Events 標(biāo)簽中顯示了在特定事件上所花的時(shí)間死陆。

圖 10. 查看渲染線程的 CPU 活動(dòng)和跟蹤事件

檢查幀渲染數(shù)據(jù)

您可以檢查應(yīng)用在主線程和 RenderThread 上渲染每個(gè)幀所用的時(shí)間,以調(diào)查導(dǎo)致界面卡頓和幀速率較低的瓶頸唧瘾。

要查看幀渲染數(shù)據(jù)措译,請(qǐng)使用可讓您 跟蹤系統(tǒng)調(diào)用 的配置 記錄跟蹤數(shù)據(jù)。記錄跟蹤數(shù)據(jù)后饰序,在名為 FRAMES 的部分下查找有關(guān)每個(gè)幀的信息领虹,如圖 11 所示。

圖 11. 每個(gè)所用時(shí)間超過 16 毫秒的幀都以紅色顯示

通過檢測(cè)您的應(yīng)用生成跟蹤日志

要生成應(yīng)用執(zhí)行的方法跟蹤求豫,您可以使用 Debug 類來檢測(cè)您的應(yīng)用塌衰。通過這種方式檢測(cè)您的應(yīng)用,可讓您更精確地控制設(shè)備何時(shí)開始和停止記錄跟蹤信息蝠嘉。此外最疆,設(shè)備還能使用您指定的名稱保存跟蹤日志,便于您日后輕松識(shí)別各個(gè)日志文件蚤告。您隨后可以使用 Android Studio 的 CPU Profiler 查看各個(gè)跟蹤日志努酸。

此外,您還可以 在 CPU Profiler 中開始和停止跟蹤罩缴,而不檢測(cè)應(yīng)用的代碼蚊逢。

在開始生成跟蹤日志之前层扶,請(qǐng)確保您的應(yīng)用有權(quán)向外部存儲(chǔ)寫入數(shù)據(jù) [WRITE_EXTERNAL_STORAGE,以便將跟蹤日志保存到該設(shè)備烙荷。

檢測(cè)您的應(yīng)用

要?jiǎng)?chuàng)建跟蹤日志镜会,請(qǐng)?jiān)谀M到y(tǒng)開始記錄跟蹤數(shù)據(jù)的位置調(diào)用 startMethodTracing()

在調(diào)用中终抽,您可以指定 .trace 文件的名稱戳表,系統(tǒng)會(huì)將它保存到一個(gè)特定于軟件包的目錄中,該目錄專門用于保存目標(biāo)設(shè)備上的永久性應(yīng)用數(shù)據(jù)昼伴,與 getExternalFilesDir() 返回的目錄相同匾旭,在大多數(shù)設(shè)備上都位于 ~/sdcard/ 目錄中。此文件包含二進(jìn)制方法跟蹤數(shù)據(jù)圃郊,以及一個(gè)包含線程和方法名稱的映射表价涝。要停止跟蹤,請(qǐng)調(diào)用 stopMethodTracing()持舆。

以下示例開始和停止記錄一個(gè)名為 sample.trace 的跟蹤日志:

    // Starts recording a trace log with the name you provide. For example, the
    // following code tells the system to start recording a .trace file to the
    // device with the name "sample.trace".
    Debug.startMethodTracing("sample");
    ...
    // The system begins buffering the generated trace data, until your
    // application calls <code><a href="/reference/android/os/Debug.html#stopMethodTracing()">stopMethodTracing()</a></code>, at which time it writes
    // the buffered data to the output file.
    Debug.stopMethodTracing();

請(qǐng)注意色瘩,如果您的應(yīng)用在未更改跟蹤日志名稱的情況下再次調(diào)用 startMethodTracing(),則會(huì)覆蓋已保存到設(shè)備的現(xiàn)有日志逸寓。要了解如何動(dòng)態(tài)更改各個(gè)跟蹤日志的名稱居兆,請(qǐng)轉(zhuǎn)到有關(guān) 保存多個(gè)日志的部分。

如果系統(tǒng)在您調(diào)用 stopMethodTracing() 之前達(dá)到緩沖區(qū)空間上限竹伸,則會(huì)停止跟蹤并向管理中心發(fā)送通知泥栖。開始和停止跟蹤的方法在您的整個(gè)應(yīng)用進(jìn)程內(nèi)均有效。也就是說勋篓,您可以在 Activity 的 onCreate(Bundle) 方法中調(diào)用 startMethodTracing()吧享,在 Activity 的 onDestroy() 方法中調(diào)用 stopMethodTracing()

請(qǐng)注意生巡,啟用分析功能后耙蔑,應(yīng)用的運(yùn)行速度會(huì)減慢。也就是說孤荣,您不應(yīng)使用分析數(shù)據(jù)來確定絕對(duì)時(shí)間(例如“運(yùn)行 foo()方法需要 2.5 秒”)。跟蹤日志中的時(shí)間信息只有在將其與先前的跟蹤日志進(jìn)行比較時(shí)才有用须揣,通過比較您就能看出最近的更改是加快還是減慢了應(yīng)用的運(yùn)行速度盐股。

部署到搭載 Android 5.0(API 級(jí)別 21)及更高版本的設(shè)備時(shí),您可以使用基于樣本的分析方式進(jìn)行分析耻卡,以減少分析對(duì)運(yùn)行時(shí)性能的影響疯汁。要啟用樣本分析,請(qǐng)調(diào)用帶有指定采樣時(shí)間間隔的 startMethodTracingSampling()(而不是調(diào)用 startMethodTracing())卵酪。系統(tǒng)會(huì)定期收集樣本幌蚊,直到您的應(yīng)用調(diào)用 stopMethodTracing()谤碳。

保存多個(gè)日志

如果您的應(yīng)用在未指定新的跟蹤日志名稱的情況下多次開始和停止方法跟蹤,設(shè)備將用新的跟蹤日志覆蓋之前的跟蹤日志溢豆,即只會(huì)保留最近的跟蹤日志蜒简。要將多個(gè)跟蹤日志保存到您的設(shè)備,應(yīng)在您的應(yīng)用每次調(diào)用 startMethodTracing()時(shí)動(dòng)態(tài)地對(duì)跟蹤日志進(jìn)行重命名漩仙。以下示例使用 SimpleDateFormat 類在對(duì)每個(gè)跟蹤日志進(jìn)行命名時(shí)包含當(dāng)前的日期和時(shí)間:

    // Uses the <code><a href="/reference/java/text/SimpleDateFormat.html">SimpleDateFormat</a></code> class to create a String with
    // the current date and time.
    SimpleDateFormat dateFormat =
            new SimpleDateFormat("dd_MM_yyyy_hh_mm_ss", Locale.getDefault());
    String logDate = dateFormat.format(new Date());
    // Applies the date and time to the name of the trace log.
    Debug.startMethodTracing(
            "sample-" + logDate);

訪問設(shè)備上的跟蹤日志

系統(tǒng)在您的設(shè)備上創(chuàng)建跟蹤日志后搓茬,您可以通過以下某種方式來訪問日志文件:

  • 使用 Device File Explorer。要打開 Device File Explorer队他,請(qǐng)依次點(diǎn)擊 View > Tool Windows > Device File Explorer(或點(diǎn)擊工具窗口欄中的 Device File Explorer 按鈕


    )卷仑。如圖 12 所示,您可以轉(zhuǎn)到應(yīng)用的軟件包專用目錄來找到 .trace 文件麸折。
    圖 12. 使用 Device File Explorer 找到跟蹤日志

  • 使用 adb pull 命令將文件復(fù)制到您的本地計(jì)算機(jī)锡凝。以下命令可將一個(gè)名為 sample.trace 的跟蹤日志從設(shè)備復(fù)制到您的本地計(jì)算機(jī)的 ~/Documents/trace-logs/ 目錄。

adb pull path-on-device/sample.trace ~/Documents/trace-logs/

隨后可以使用 CPU Profiler 導(dǎo)入跟蹤文件垢啼。

申明:開始和結(jié)束的圖片來源網(wǎng)絡(luò)私爷,侵刪

End

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市膊夹,隨后出現(xiàn)的幾起案子衬浑,更是在濱河造成了極大的恐慌,老刑警劉巖放刨,帶你破解...
    沈念sama閱讀 218,451評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件工秩,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡进统,警方通過查閱死者的電腦和手機(jī)助币,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來螟碎,“玉大人眉菱,你說我怎么就攤上這事〉舴郑” “怎么了俭缓?”我有些...
    開封第一講書人閱讀 164,782評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)酥郭。 經(jīng)常有香客問我华坦,道長(zhǎng),這世上最難降的妖魔是什么不从? 我笑而不...
    開封第一講書人閱讀 58,709評(píng)論 1 294
  • 正文 為了忘掉前任惜姐,我火速辦了婚禮,結(jié)果婚禮上椿息,老公的妹妹穿的比我還像新娘歹袁。我一直安慰自己坷衍,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,733評(píng)論 6 392
  • 文/花漫 我一把揭開白布条舔。 她就那樣靜靜地躺著枫耳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評(píng)論 1 305
  • 那天穷劈,我揣著相機(jī)與錄音,去河邊找鬼仑最。 笑死,一個(gè)胖子當(dāng)著我的面吹牛帆喇,可吹牛的內(nèi)容都是我干的警医。 我是一名探鬼主播,決...
    沈念sama閱讀 40,320評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼坯钦,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼预皇!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起婉刀,我...
    開封第一講書人閱讀 39,241評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤吟温,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后突颊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲁豪,經(jīng)...
    沈念sama閱讀 45,686評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,878評(píng)論 3 336
  • 正文 我和宋清朗相戀三年律秃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了爬橡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,992評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡棒动,死狀恐怖糙申,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情船惨,我是刑警寧澤柜裸,帶...
    沈念sama閱讀 35,715評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站掷漱,受9級(jí)特大地震影響粘室,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜卜范,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,336評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鹿榜。 院中可真熱鬧海雪,春花似錦锦爵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至湾宙,卻和暖如春樟氢,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背侠鳄。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工埠啃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伟恶。 一個(gè)月前我還...
    沈念sama閱讀 48,173評(píng)論 3 370
  • 正文 我出身青樓碴开,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親博秫。 傳聞我的和親對(duì)象是個(gè)殘疾皇子潦牛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,947評(píng)論 2 355

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