Android Studio 3.0 利用 Android Profiler 測量應用效能

往事惘逝發表於2018-08-22

Android Studio 3.0 採用全新的 Android Profiler 視窗取代 Android Monitor 工具。 這些全新的分析工具能夠提供關於應用 CPU記憶體網路活動的實時資料。

您可以執行基於樣本的函式跟蹤來記錄程式碼執行時間、採集堆轉儲資料、檢視記憶體分配,以及檢視網路傳輸檔案的詳情。

Android Profiler 的使用方法

Android Profiler 的開啟步驟

要開啟 Android Profiler 視窗,請按以下步驟操作:

  1. 點選 View > Tool Windows > Android Profiler(也可以點選工具欄中的 Android Profiler Android Studio 3.0 利用 Android Profiler 測量應用效能)。
  2. 從 Android Profiler 工具欄中選擇您想要分析的裝置和應用程式。 如果您通過 USB 連線了某個裝置但該裝置未在裝置列表中列出,請確保您已啟用 USB 除錯(如果您使用的是 Android Emulator 或已取得 root 許可權的裝置,Android Profiler 將列出所有正在執行的程式,即使這些程式可能無法除錯。 當您釋出可除錯應用時,將會預設選擇此程式)。
  3. Android Profiler 視窗頂部(如下圖所示),選擇您想要分析的裝置和應用程式。

Android Profiler 共享時間線的檢視顯示如下圖所示:

Android Studio 3.0 利用 Android Profiler 測量應用效能
Android Profiler 目前可顯示共享時間線檢視,可以在按鈕①的位置選擇裝置,通過按鈕②的位置選擇想要的app程式,工具最底部顯示了一個時間軸,其中包含了CPU、記憶體和網路使用的實時圖。該視窗還包括時間軸縮放控制按鈕③,一個跳轉到實時更新的按鈕④,以及顯示活動狀態、使用者輸入事件和螢幕旋轉事件⑤的事件時間軸。

當您啟動 Android Profiler 後,它會持續收集分析資料,直至您斷開裝置連線或點選 Close Android Studio 3.0 利用 Android Profiler 測量應用效能

此共享時間線檢視只顯示時間線圖表。 要使用詳細分析工具,請點選與您想檢視的效能資料對應的圖表。 例如,要使用工具檢視堆資料和跟蹤記憶體分配,可點選 MEMORY 圖表。

但並不是所有分析資料均預設可見。 如果您看到一條訊息,顯示“Advanced profiling is unavailable for the selected process”,則需在執行配置中啟用高階分析

啟用高階分析

要顯示高階分析資料,Android Studio 必須在您編譯後的應用中插入監控邏輯。高階分析工具提供的功能包括:

  • Event 時間線(所有分析器視窗中均有)
  • 分配物件數量(Memory Profiler 中)
  • 垃圾回收 Event(Memory Profiler 中)
  • 有關所有傳輸的檔案的詳情(Network Profiler 中)

要啟用高階分析,請按以下步驟操作:

  1. 選擇 Run > Edit Configurations
  2. 在左側窗格中選擇您的應用模組。
  3. 點選 Profiling 標籤,然後勾選 Enable advanced profiling

現在重新構建並執行您的應用,即可獲取完整的分析功能。但請注意,高階分析會減緩您的構建速度,所以僅當您想要開始分析應用時才啟用此功能。

注:對於原生程式碼,不可使用高階分析功能。 如果您的應用是純原生應用(不含 Java Activity 類),則不可使用高階分析功能。 如果您的應用使用了 JNI,則可使用部分高階分析功能,例如 Event 時間線、GC Event、Java 分配物件和基於 Java 的網路活動,但不能檢測基於原生的分配和網路活動。

使用 CPU Profiler 檢查 CPU 活動 和函式跟蹤

使用 CPU Profiler 檢查 CPU 活動 和函式跟蹤 CPU Profiler 可幫助您實時檢查應用的 CPU 使用率和執行緒活動,並記錄函式跟蹤,以便您可以優化和除錯您的應用程式碼。點選 Android Profiler 視窗中的 CPU 時間線中的任意位置即可開啟 CPU Profiler

為什麼要分析 CPU 使用率

最大限度減少應用的 CPU 使用率具有許多優勢,如提供更快更順暢的使用者體驗,以及延長裝置電池續航時間。 它還可幫助應用在各種新舊裝置上保持良好效能。 與應用互動時,您可以使用 CPU Profiler 監控 CPU 使用率和執行緒活動。 不過,如需瞭解應用如何執行其程式碼的詳細資訊,您應記錄和檢查函式跟蹤

對於應用程式中的每個執行緒,您可以檢視一段時間內執行了哪些函式,以及在其執行期間每個函式消耗的 CPU 資源。 您還可以使用函式跟蹤來識別呼叫方和被呼叫方。 呼叫方指呼叫其他函式的函式,而被呼叫方是指被其他函式呼叫的函式。 您可以使用此資訊確定哪些函式負責呼叫常常會消耗大量特定資源的任務,並嘗試優化應用程式碼以避免不必要的工作。

如果您想收集可幫助您檢查原生系統程式的詳細系統級資料,並解決掉幀引起的介面卡頓,您應使用 systrace

或者,如果您想匯出您使用 Debug 類捕獲的 .trace 檔案,您應使用 Traceview

CPU Profiler 概覽

當您開啟 CPU Profiler 時,它將立即開始顯示應用的 CPU 使用率和執行緒活動。CPU Profiler 的預設檢視如下圖所示:

CPU Profiler

如圖所示,CPU Profiler 的預設檢視包括以下內容:

  1. Event 時間線: 顯示應用中在其生命週期不同狀態間轉換的活動,並表明使用者與裝置的互動,包括螢幕旋轉 Event。 如需瞭解有關 Event 時間線的更多資訊,包括如何啟用它,請閱讀 啟用高階分析
  2. CPU 時間線: 顯示應用的實時 CPU 使用率(以佔總可用 CPU 時間的百分比表示)以及應用使用的匯流排程數。 此時間線還顯示其他程式的 CPU 使用率(如系統程式或其他應用),以便您可以將其與您的應用使用率進行對比。 通過沿時間線的水平軸移動滑鼠,您還可以檢查歷史 CPU 使用率資料。
  3. 執行緒活動時間線: 列出屬於應用程式的每個執行緒並使用下面列出的顏色沿時間線標示它們的活動。 在您記錄一個函式跟蹤後,您可以從此時間線中選擇一個執行緒以在跟蹤窗格中檢查其資料。
  • 綠色: 表示執行緒處於活動狀態或準備使用 CPU。 即,它正在“執行中”或處於“可執行”狀態。
  • 黃色: 表示執行緒處於活動狀態,但它正在等待一個 I/O 操作(如磁碟或網路 I/O),然後才能完成它的工作。
  • 灰色: 表示執行緒正在休眠且沒有消耗任何 CPU 時間。當執行緒需要訪問尚不可用的資源時偶爾會發生這種情況。執行緒進入自主休眠或核心將此執行緒置於休眠狀態,直到所需的資源可用。
  1. 記錄配置: 允許您選擇以下選項之一以確定分析器記錄函式跟蹤的方式。
  • Sampled: 一個預設配置,在應用執行期間頻繁捕獲應用的呼叫堆疊。 分析器比較捕獲的資料集以推導與應用程式碼執行有關的時間和資源使用資訊。 基於“Sampled”的跟蹤的固有問題是,如果應用在捕獲呼叫堆疊後進入一個函式並在下一次捕獲前退出該函式,則分析器不會記錄該函式呼叫。 如果您對此類生命週期很短的跟蹤函式感興趣,您應使用“Instrumented”跟蹤。
  • Instrumented: 一個預設配置,在執行時設定應用以在每個函式呼叫的開始和結束時記錄時間戳。 它收集時間戳並進行比較,以生成函式跟蹤資料,包括時間資訊和 CPU 使用率。 請注意,與設定每個函式關聯的開銷會影響執行時效能,並可能會影響分析資料,對於生命週期相對較短的函式,這一點更為明顯。 此外,如果應用短時間內執行大量函式,則分析器可能會迅速超出它的檔案大小限制,且不能再記錄更多跟蹤資料。
  • Edit configurations: 允許您更改上述“Sampled”和“Instrumented”記錄配置的某些預設值,並將它們另存為自定義配置。 如需瞭解更多資訊,請轉到建立記錄配置部分。
  1. 記錄按鈕: 用於開始和停止記錄函式跟蹤。 如需瞭解更多資訊,請轉到記錄和檢查函式跟蹤部分。

注: 分析器還會報告 Android Studio 和 Android 平臺新增到您的應用程式(如 JDWP、Profile Saver、Studio:VMStats、Studio:Perfa 以及 Studio:Heartbeat,儘管它們線上程活動時間線中顯示的確切名稱可能有所不同)的執行緒 CPU 使用率。 這表示 CPU 時間線中應用的 CPU 使用率還可反映這些執行緒使用的 CPU 時間。 您可以線上程活動時間線中檢視其中的一些執行緒並監控其活動。 (不過,由於分析器執行緒執行原生程式碼,因此,您無法為它們記錄函式跟蹤資料。)Android Studio 將報告此資料,以便當執行緒活動及 CPU 使用率實際上是由應用程式碼引發時,您可以輕鬆識別。

記錄和檢查函式跟蹤

要開始記錄函式跟蹤,從下拉選單中選擇 SampledInstrumented 記錄配置,或選擇您建立的自定義記錄配置,然後點選 Record Android Studio 3.0 利用 Android Profiler 測量應用效能。 與應用互動並在完成後點選 Stop recording Android Studio 3.0 利用 Android Profiler 測量應用效能。 分析器將自動選擇記錄的時間範圍,並在函式跟蹤窗格中顯示其跟蹤資訊。如果您想檢查另一個執行緒的函式跟蹤,只需從執行緒活動時間線中選中它。 記錄函式跟蹤後的 CPU Profiler 檢視,如下圖所示:

CPU Profiler
如圖所示,記錄函式跟蹤後的 CPU Profiler 檢視包括以下內容:

  1. 選擇時間範圍: 用於確定您要在跟蹤窗格中檢查所記錄時間範圍的哪一部分。 當您首次記錄函式跟蹤時,CPU Profiler 將在 CPU 時間線中自動選擇您的記錄的完整長度。 如果您想僅檢查所記錄時間範圍一小部分的函式跟蹤資料,您可以點選並拖動突出顯示的區域邊緣以修改其長度。
  2. 時間戳: 用於表示所記錄函式跟蹤的開始和結束時間(相對於分析器從裝置開始收集 CPU 使用率資訊的時間)。 在選擇時間範圍時,您可以點選時間戳以自動選擇完整記錄,如果您有多個要進行切換的記錄,則此做法尤其有用。
  3. 跟蹤窗格: 用於顯示您所選的時間範圍和執行緒的函式跟蹤資料。 僅在您至少記錄一個函式跟蹤後此窗格才會顯示。 在此窗格中,您可以選擇想如何檢視每個堆疊追蹤(使用跟蹤標籤),以及如何測量執行時間(使用時間引用下拉選單)。
  4. 選擇後,可通過 Top Down 樹、Bottom Up 樹、呼叫圖表火焰圖的形式顯示您的函式跟蹤。 您可以在下文中瞭解每個跟蹤窗格標籤的更多資訊。
  5. 從下拉選單中選擇以下選項之一,以確定如何測量每個函式呼叫的時間資訊:
  • Wall clock time: 壁鐘時間資訊表示實際經過的時間。
  • Thread time: 執行緒時間資訊表示實際經過的時間減去執行緒沒有消耗 CPU 資源的任意時間部分。對於任何給定函式,其執行緒時間始終少於或等於其壁鐘時間。 使用執行緒時間可以讓您更好地瞭解執行緒的實際 CPU 使用率中有多少是給定函式消耗的。

使用 Memory Profiler 檢視 Java 堆和記憶體分配

Memory Profiler 是 Android Profiler 中的一個元件,可幫助您識別導致應用卡頓、凍結甚至崩潰的記憶體洩漏和流失。 它顯示一個應用記憶體使用量的實時圖表,讓您可以捕獲堆轉儲、強制執行垃圾回收以及跟蹤記憶體分配。點選 Android Profiler 視窗中的 MEMORY 時間線中的任意位置即可開啟 Memory Profiler。或者,您可以在命令列中使用 dumpsys 檢查您的應用記憶體,同時檢視 logcat 中的 GC Event

為什麼應分析您的應用記憶體

Android 提供一個託管記憶體環境—當它確定您的應用不再使用某些物件時,垃圾回收器會將未使用的記憶體釋放回堆中。 雖然 Android 查詢未使用記憶體的方式在不斷改進,但對於所有 Android 版本,系統都必須在某個時間點短暫地暫停您的程式碼。 大多數情況下,這些暫停難以察覺。 不過,如果您的應用分配記憶體的速度比系統回收記憶體的速度快,則當收集器釋放足夠的記憶體以滿足您的分配需要時,您的應用可能會延遲。 此延遲可能會導致您的應用跳幀,並使系統明顯變慢。

儘管您的應用不會表現出變慢,但如果存在記憶體洩漏,則即使應用在後臺執行也會保留該記憶體。 此行為會強制執行不必要的垃圾回收 Event,因而拖慢系統的記憶體效能。 最後,系統被迫終止您的應用程式以回收記憶體。 然後,當使用者返回您的應用時,它必須完全重啟。

為幫助防止這些問題,您應使用 Memory Profiler 執行以下操作:

  • 在時間線中查詢可能會導致效能問題的不理想的記憶體分配模式。
  • 轉儲 Java 堆以檢視在任何給定時間哪些物件耗盡了使用記憶體。長時間進行多個堆轉儲可幫助識別記憶體洩漏。
  • 記錄正常使用者互動和極端使用者互動期間的記憶體分配以準確識別您的程式碼在何處短時間分配了過多物件,或分配了洩漏的物件。

如需瞭解可減少應用記憶體使用的程式設計做法,請閱讀管理您的應用記憶體

Memory Profiler 概覽

當您首次開啟 Memory Profiler 時,您將看到一條表示應用記憶體使用量的詳細時間線,並可訪問用於強制執行垃圾回收、捕捉堆轉儲和記錄記憶體分配的各種工具。Memory Profiler 的預設檢視如下圖所示:

Memory Profiler

如圖所示,Memory Profiler 的預設檢視包括以下各項:

  1. 用於強制執行垃圾回收 Event 的按鈕。
  2. 用於捕獲堆轉儲的按鈕
  3. 用於記錄記憶體分配情況的按鈕。 此按鈕僅在連線至執行 Android 7.1 或更低版本的裝置時才會顯示。
  4. 用於放大/縮小時間線的按鈕。
  5. 用於跳轉至實時記憶體資料的按鈕。
  6. Event 時間線,其顯示活動狀態、使用者輸入 Event 和螢幕旋轉 Event。
  7. 記憶體使用量時間線,其包含以下內容:
  • 一個顯示每個記憶體類別使用多少記憶體的堆疊圖表,如左側的 y 軸以及頂部的彩色鍵所示。
  • 虛線表示分配的物件數,如右側的 y 軸所示。
  • 用於表示每個垃圾回收 Event 的圖示。

不過,如果您使用的是執行 Android 7.1 或更低版本的裝置,則預設情況下,並不是所有分析資料均可見。 如果您看到一條訊息,其顯示“Advanced profiling is unavailable for the selected process”,則需要啟用高階分析以檢視下列內容:

  • Event 時間線
  • 分配的物件數
  • 垃圾回收 Event

在 Android 8.0 及更高版本上,始終為可除錯應用啟用高階分析。

如何計算記憶體

您在 Memory Profiler 頂部看到的數字取決於您的應用根據 Android 系統機制所提交的所有私有記憶體頁面數。 此計數不包含與系統或其他應用共享的頁面。 Memory Profiler 頂部的記憶體計數圖例,如下圖所示:

Memory Profiler Counts

記憶體計數中的類別如下所示:

  • Java: 從 Java 或 Kotlin 程式碼分配的物件記憶體。
  • Native: 從 C 或 C++ 程式碼分配的物件記憶體。

即使您的應用中不使用 C++,您也可能會看到此處使用的一些原生記憶體,因為 Android 框架使用原生記憶體代表您處理各種任務,如處理影像資源和其他圖形時,即使您編寫的程式碼採用 Java 或 Kotlin 語言。

  • Graphics: 圖形緩衝區佇列向螢幕顯示畫素(包括 GL 表面、GL 紋理等等)所使用的記憶體。(請注意,這是與 CPU 共享的記憶體,不是 GPU 專用記憶體。)
  • Stack: 您的應用中的原生堆疊和 Java 堆疊使用的記憶體。 這通常與您的應用執行多少執行緒有關。
  • Code: 您的應用用於處理程式碼和資源(如 dex 位元組碼、已優化或已編譯的 dex 碼、.so 庫和字型)的記憶體。
  • Other: 您的應用使用的系統不確定如何分類的記憶體。
  • Allocated: 您的應用分配的 Java/Kotlin 物件數。 它沒有計入 C 或 C++ 中分配的物件。

當連線至執行 Android 7.1 及更低版本的裝置時,此分配僅在 Memory Profiler 連線至您執行的應用時才開始計數。 因此,您開始分析之前分配的任何物件都不會被計入。 不過,Android 8.0 附帶一個裝置內建分析工具,該工具可記錄所有分配,因此,在 Android 8.0 及更高版本上,此數字始終表示您的應用中待處理的 Java 物件總數。

與以前的 Android Monitor 工具中的記憶體計數相比,新的 Memory Profiler 以不同的方式記錄您的記憶體,因此,您的記憶體使用量現在看上去可能會更高些。 Memory Profiler 監控的類別更多,這會增加總的記憶體使用量,但如果您僅關心 Java 堆記憶體,則“Java”項的數字應與以前工具中的數值相似。

然而,Java 數字可能與您在 Android Monitor 中看到的數字並非完全相同,這是因為應用的 Java 堆是從 Zygote 啟動的,而新數字則計入了為它分配的所有實體記憶體頁面。 因此,它可以準確反映您的應用實際使用了多少實體記憶體。

注:目前,Memory Profiler 還會顯示應用中的一些誤報的原生記憶體使用量,而這些記憶體實際上是分析工具使用的。 對於大約 100000 個物件,最多會使報告的記憶體使用量增加 10MB。 在這些工具的未來版本中,這些數字將從您的資料中過濾掉。

檢視記憶體分配

記憶體分配顯示記憶體中每個物件是如何分配的。 具體而言,Memory Profiler 可為您顯示有關物件分配的以下資訊:

  • 分配哪些型別的物件以及它們使用多少空間。
  • 每個分配的堆疊追蹤,包括在哪個執行緒中。
  • 物件在何時被取消分配(僅當使用執行 Android 8.0 或更高版本的裝置時)。

如果您的裝置執行 Android 8.0 或更高版本,您可以隨時按照下述方法檢視您的物件分配: 只需點選並按住時間線,並拖動選擇您想要檢視分配的區域。 不需要開始記錄會話,因為 Android 8.0 及更高版本附帶裝置內建分析工具,可持續跟蹤您的應用分配。如下如所示:

Android Studio 3.0 利用 Android Profiler 測量應用效能

如果您的裝置執行 Android 7.1 或更低版本,則在 Memory Profiler 工具欄中點選 Record memory allocations Android Studio 3.0 利用 Android Profiler 測量應用效能。 記錄時,Android Monitor 將跟蹤您的應用中進行的所有分配。 操作完成後,點選 Stop recording Android Studio 3.0 利用 Android Profiler 測量應用效能(同一個按鈕)以檢視分配。如下如所示:

Android Studio 3.0 利用 Android Profiler 測量應用效能

在選擇一個時間線區域後(或當您使用執行 Android 7.1 或更低版本的裝置完成記錄會話時),已分配物件的列表將顯示在時間線下方,按類名稱進行分組,並按其堆計數排序。

注:在 Android 7.1 及更低版本上,您最多可以記錄 65535 個分配。 如果您的記錄會話超出此限值,則記錄中僅儲存最新的 65535 個分配。 (在 Android 8.0 及更高版本中,則沒有實際的限制。)

要檢查分配記錄,請按以下步驟操作:

  1. 瀏覽列表以查詢堆計數異常大且可能存在洩漏的物件。 為幫助查詢已知類,點選 Class Name 列標題以按字母順序排序。 然後點選一個類名稱。 此時在右側將出現 Instance View 窗格,顯示該類的每個例項,如下圖中所示。
  2. Instance View 窗格中,點選一個例項。 此時下方將出現 Call Stack 標籤,顯示該例項被分配到何處以及哪個執行緒中。
  3. Call Stack 標籤中,點選任意行以在編輯器中跳轉到該程式碼。 有關每個已分配物件的詳情在右側的 Instance View 中的顯示,如下圖所示:
    Memory Profiler Allocations Detail

預設情況下,左側的分配列表按類名稱排列。在列表頂部,您可以使用右側的下拉選單在以下排列方式之間進行切換:

  • Arrange by class: 基於類名稱對所有分配進行分組。
  • Arrange by package: 基於軟體包名稱對所有分配進行分組。
  • Arrange by callstack: 將所有分配分組到其對應的呼叫堆疊。

捕獲堆轉儲

堆轉儲顯示在您捕獲堆轉儲時您的應用中哪些物件正在使用記憶體。 特別是在長時間的使用者會話後,堆轉儲會顯示您認為不應再位於記憶體中卻仍在記憶體中的物件,從而幫助識別記憶體洩漏。 在捕獲堆轉儲後,您可以檢視以下資訊:

  • 您的應用已分配哪些型別的物件,以及每個型別分配多少。
  • 每個物件正在使用多少記憶體。
  • 在程式碼中的何處仍在引用每個物件。
  • 物件所分配到的呼叫堆疊(目前,如果您在記錄分配時捕獲堆轉儲,則只有在 Android 7.1 及更低版本中,堆轉儲才能使用呼叫堆疊)。

要捕獲堆轉儲,在 Memory Profiler 工具欄中點選 Dump Java heap Android Studio 3.0 利用 Android Profiler 測量應用效能。 在轉儲堆期間,Java 記憶體量可能會暫時增加。 這很正常,因為堆轉儲與您的應用發生在同一程式中,並需要一些記憶體來收集資料。

堆轉儲顯示在記憶體時間線下,顯示堆中的所有類型別,如下圖所示:

Memory Profiler Dump

注:如果您需要更精確地瞭解轉儲的建立時間,可以通過呼叫 dumpHprofData() 在應用程式碼的關鍵點建立堆轉儲。

要檢查您的堆,請按以下步驟操作:

  1. 瀏覽列表以查詢堆計數異常大且可能存在洩漏的物件。 為幫助查詢已知類,點選 Class Name 列標題以按字母順序排序。 然後點選一個類名稱。此時在右側將出現 Instance View 窗格,顯示該類的每個例項,如下圖中所示。
  2. Instance View 窗格中,點選一個例項。此時下方將出現 References,顯示該物件的每個引用。 或者,點選例項名稱旁的箭頭以檢視其所有欄位,然後點選一個欄位名稱檢視其所有引用。 如果您要檢視某個欄位的例項詳情,右鍵點選該欄位並選擇 Go to Instance
  3. References 標籤中,如果您發現某個引用可能在洩漏記憶體,則右鍵點選它並選擇 Go to Instance。 這將從堆轉儲中選擇對應的例項,顯示您自己的例項資料。

預設情況下,堆轉儲不會向您顯示每個已分配物件的堆疊追蹤。 要獲取堆疊追蹤,在點選 Dump Java heap 之前,您必須先開始記錄記憶體分配。然後,您可以在 Instance View 中選擇一個例項,並檢視 Call Stack 標籤以及 References 標籤,如下圖所示。不過,在您開始記錄分配之前,可能已分配一些物件,因此,呼叫堆疊不能用於這些物件。包含呼叫堆疊的例項在圖示 上用一個“堆疊”標誌表示。(遺憾的是,由於堆疊追蹤需要您執行分配記錄,因此,您目前無法在 Android 8.0 上檢視堆轉儲的堆疊追蹤。)

預設情況下,堆轉儲不會向您顯示每個已分配物件的堆疊追蹤。 要獲取堆疊追蹤,在點選 Dump Java heap 之前,您必須先開始記錄記憶體分配。然後,您可以在 Instance View 中選擇一個例項,並檢視 Call Stack 標籤以及 References 標籤,如下圖所示。不過,在您開始記錄分配之前,可能已分配一些物件,因此,呼叫堆疊不能用於這些物件。包含呼叫堆疊的例項在圖示 Android Studio 3.0 利用 Android Profiler 測量應用效能 上用一個“堆疊”標誌表示。(遺憾的是,由於堆疊追蹤需要您執行分配記錄,因此,您目前無法在 Android 8.0 上檢視堆轉儲的堆疊追蹤。)

在您的堆轉儲中,請注意由下列任意情況引起的記憶體洩漏:

  • 長時間引用 Activity、Context、View、Drawable 和其他物件,可能會保持對 Activity 或 Context 容器的引用。
  • 可以保持 Activity 例項的非靜態內部類,如 Runnable。
  • 物件保持時間超出所需時間的快取。

捕獲堆轉儲需要的持續時間標示在時間線中,如下圖所示:

Memory Profiler Dump Stacktrace

在類列表中,您可以檢視以下資訊:

  • Heap Count: 堆中的例項數。
  • Shallow Size: 此堆中所有例項的總大小(以位元組為單位)。
  • Retained Size: 為此類的所有例項而保留的記憶體總大小(以位元組為單位)。

在類列表頂部,您可以使用左側下拉選單在以下堆轉儲之間進行切換:

  • Default heap: 系統未指定堆時。
  • App heap: 您的應用在其中分配記憶體的主堆。
  • Image heap: 系統啟動映像,包含啟動期間預載入的類。 此處的分配保證絕不會移動或消失。
  • Zygote heap: 寫時複製堆,其中的應用程式是從 Android 系統中派生的。

預設情況下,此堆中的物件列表按類名稱排列。 您可以使用其他下拉選單在以下排列方式之間進行切換:

  • Arrange by class: 基於類名稱對所有分配進行分組。
  • Arrange by package: 基於軟體包名稱對所有分配進行分組。
  • Arrange by callstack: 將所有分配分組到其對應的呼叫堆疊。此選項僅在記錄分配期間捕獲堆轉儲時才有效。即使如此,堆中的物件也很可能是在您開始記錄之前分配的,因此這些分配會首先顯示,且只按類名稱列出。

預設情況下,此列表按 Retained Size 列排序。 您可以點選任意列標題以更改列表的排序方式。

在 Instance View 中,每個例項都包含以下資訊:

  • Depth: 從任意 GC 根到所選例項的最短 hop 數。
  • Shallow Size: 此例項的大小。
  • Retained Size: 此例項支配的記憶體大小(根據 dominator 樹)。

將堆轉儲另存為 HPROF

在捕獲堆轉儲後,僅當分析器執行時才能在 Memory Profiler 中檢視資料。 當您退出分析會話時,您將丟失堆轉儲。 因此,如果您要儲存堆轉儲以供日後檢視,可通過點選時間線下方工具欄中的 Export heap dump as HPROF file Android Studio 3.0 利用 Android Profiler 測量應用效能,將堆轉儲匯出到一個 HPROF 檔案中。 在顯示的對話方塊中,確保使用 .hprof 字尾儲存檔案。

然後,通過將此檔案拖到一個空的編輯器視窗(或將其拖到檔案標籤欄中),您可以在 Android Studio 中重新開啟該檔案。

要使用其他 HPROF 分析器(如 jhat),您需要將 HPROF 檔案從 Android 格式轉換為 Java SE HPROF 格式。 您可以使用 android_sdk/platform-tools/ 目錄中提供的 hprof-conv 工具執行此操作。 執行包括以下兩個引數的 hprof-conv 命令:原始 HPROF 檔案和轉換後 HPROF 檔案的寫入位置。 例如:

hprof-conv heap-original.hprof heap-converted.hprof
複製程式碼

分析記憶體的技巧

使用 Memory Profiler 時,您應對應用程式碼施加壓力並嘗試強制記憶體洩漏。 在應用中引發記憶體洩漏的一種方式是,先讓其執行一段時間,然後再檢查堆。 洩漏在堆中可能逐漸匯聚到分配頂部。 不過,洩漏越小,您越需要執行更長時間的應用才能看到洩漏。

您還可以通過以下方式之一觸發記憶體洩漏:

  • 將裝置從縱向旋轉為橫向,然後在不同的 Activity 狀態下反覆操作多次。 旋轉裝置經常會導致應用洩漏 ActivityContextView 物件,因為系統會重新建立 Activity,而如果您的應用在其他地方保持對這些物件之一的引用,系統將無法對其進行垃圾回收。
  • 處於不同的 Activity 狀態時,在您的應用與另一個應用之間切換(導航到主螢幕,然後返回到您的應用)。

提示: 您還可以使用 monkeyrunner 測試框架執行上述步驟。

利用 Network Profiler 檢查網路流量

Network Profiler 能夠在時間線上顯示實時網路活動,包括髮送和接收的資料以及當前的連線數。 這便於您檢視應用傳輸資料的方式和時間,並據此對底層程式碼進行適當優化。點選 Android Profiler 視窗中的 NETWORK 時間線中的任意位置即可開啟 Network Profiler

為什麼應分析應用的網路活動

當您的應用向網路發出請求時,裝置必須使用高功耗的移動或 WLAN 無線裝置來收發資料包。無線裝置不僅要消耗電力來傳輸資料,還需要消耗額外的電力來開啟並且不鎖定螢幕。

使用 Network Profiler,您可以查詢頻繁出現的短時網路活動峰值,這意味著您的應用需要經常開啟無線裝置,或需要長時間不鎖定螢幕以處理集中出現的大量短時請求。這種模式說明您可以通過批量處理網路請求,減少必須開啟無線裝置來傳送或接收資料的次數,從而優化應用,改善電池續航表現。這種方式還能讓無線裝置調整到低能耗模式,延長批量處理請求之間的間隔時間,節省能耗。

要詳細瞭解優化應用網路活動 的相關技巧,請參閱減少網路耗電量

Network Profiler 概覽

Network Profiler 的預設檢視如下圖所示:

Network Profiler
視窗的頂部的①處,可以看見wifi無線訊號的強弱,在時間線上可以在②處點選和拖動一部分的時間線來檢測流量,然後在視窗③中會顯示所選時間段內收發的檔案,包括檔名,大小,型別,狀態和花費時間,你可以對視窗③的列表根據列來進行排序。還可以檢視所選時間段的詳細拆分,拆分的timeline可以顯示檔案是什麼時候收發的,點選視窗3的其中一個檔案,可以在視窗④中檢視檔案的詳細資訊。通過切換視窗④上方標籤可以檢視響應資料、標題資訊和呼叫堆疊。

注: 必須啟用高階分析才能從時間線中選擇要檢查的片段,檢視傳送和接收的檔案列表,或檢視有關所傳送或接收的選定檔案的詳細資訊。 要啟用高階分析,請參閱啟用高階分析

排查網路連線問題

如果 Network Profiler 檢測到流量值,但無法識別任何受支援的網路請求,您會收到以下錯誤訊息:

"Network Profiling Data Unavailable: There is no information for the network traffic you've selected."

Network Profiler 目前只支援 HttpURLConnectionOkHttp 網路連線庫。如果您的應用使用的是其他網路連線庫,則可能無法在 Network Profiler 中檢視網路活動。 如果您收到這條錯誤訊息,但您的應用確實使用了 HttpURLConnection 或 OkHttp,請報告錯誤搜尋 Issue Tracker,在與您的問題有關的現有報告中加入您的反饋。 此外,您還可以利用以下資源請求提供關於其他庫的支援。

致謝

利用 Android Profiler 測量應用效能

Measure app performance with Android Profiler

相關文章