效能評估與分析範例

Stay organized with collections Save and categorize content based on your preferences.

以下範例說明如何使用 Macrobenchmark 的系統追蹤功能,並透過記憶剖析,來評估和改善特定類型的效能問題。

使用 systrace 對應用程式的啟動進行偵錯

如要對啟動時間進行偵錯,推薦您使用 systrace 記錄。Systrace 是一個系統,它能利用預先編譯的程式碼來計算出特定事件發生所需的時間長度。這些追蹤記錄可讓您瞭解應用程式的運作情形,甚至是整個系統中的各個程序。Android 平台和 Jetpack 程式庫會對應用程式中眾多的重要事件進行檢測,系統中也會留下記錄。您也可以自訂追蹤記錄來檢測應用程式,記錄將會顯示在相同的 systrace 視覺化工具中,方便您掌握應用程式的運作全貌。

使用 systrace 或 Perfetto

如要進一步瞭解 systrace 基本使用方式,請觀看以下影片:應用程式偵錯效能

為分析啟動時間,您必須先瞭解啟動期間發生的狀況。除了本頁面提供的說明外,如需更多資訊,您可以在應用程式啟動過程記錄文件中,找到應用程式啟動程序概述。

應用程式啟動的各個階段如下:

  • 啟動程序
  • 初始化通用應用程式物件
  • 建立及初始化作業
  • 加載版面配置
  • 繪製第一個框架

啟動類型有下列幾個階段:

  • 冷啟動:應用程式在裝置開啟後首次啟動,或是在遭到使用者或系統終止程序後首次啟動,就會進入這個階段。此時啟動作業會建立一個新程序,無暫存狀態
  • 暖啟動:應用程式已在背景執行,但必須重新建立作業並移至前景運作,就會進入這個階段。為重新建立作業,不是重複使用已存在的程序,就是利用暫存狀態重新建立程序。Macrobenchmark 測試程式庫可支援採用第一選項的持續性暖啟動測試。
  • 熱啟動:當程序和作業都仍在執行中,只需將其移至前景、視需要可能重新建立一些物件,並轉譯新的前景作業時,就會進入這個階段。這是最省時的啟動狀況。

我們建議使用「開發人員選項」中內建的裝置端系統追蹤應用程式,來擷取系統追蹤記錄。如要使用指令列工具,Android 10 (API 層級 29) 以上版本可運用 Perfetto,較舊版的裝置則應使用 systrace

請注意,「第一個框架」在用詞上有點不夠精準,因為各個應用程式在建立初始作業後,接續的處理方式上會有很大的差異。有些應用程式會持續加載多個框架,而有些甚至會立即展開次級作業。

在應用程式啟動完成之後,我們建議盡可能進行 reportFullyDrawn 呼叫 (適用於 Android 10 以上版本)。

針對這些系統追蹤記錄,您需要注意的地方包括:

監控系統衝突
圖1. 受監控保護的資源如果發生內部競爭,可能會造成應用程式的啟動作業大幅延遲。

同步綁定資料傳輸
圖2. 從應用程式的主要路徑中找出不必要的資料傳輸。

垃圾資訊即時收集作業
圖3.即時的垃圾資訊收集作業相當常見,對系統影響程度也相對較低。但如果經常發生,建議利用 Android Studio 記憶體分析器進行調查。

啟動期間的 I/O
圖4. 查看啟動期間的 I/O 狀況,並尋找較嚴重的停頓問題。

請注意如圖 4,如有其他程序同時執行 I/O 可能會造成衝突,因此請確保沒有其他程序同時在進行。

其他執行緒的重大作業會干擾 UI 執行緒,因此請留意啟動期間的背景作業。請注意,不同裝置可能會有不同的 CPU 組態,因此可同時執行的執行緒數量將可能因裝置而異。

另請參考指南:造成資源浪費的常見原因

使用 Android Studio 記憶體分析器

Android Studio 記憶體分析器具有強大的功能,可釋放記憶體被佔用或不當使用模式造成的記憶體壓力。可讓您即時查看物件配置與回收情況。

要修正應用程式的記憶體問題,您可以使用記憶體分析器來追蹤垃圾資訊收集進行的原因和頻率,以及是否可能發生記憶體流失,導致您的資訊量堆積過多。

剖析應用程式記憶體可細分為下列步驟:

1.偵測記憶體問題

如要偵測記憶體問題,請先錄下一段應用程式記憶體剖析的過程。接著找出記憶體用量增加,而最終觸發垃圾收集作業的物件。

物件數量增加
圖5.記憶體分析器顯示,隨著時間進行,各處分布的物件數量持續增加。

垃圾資訊收集作業
圖6.呈現垃圾資訊收集事件的記憶體分析。{圖檔/附文字說明}

一旦辨識出會增加記憶體壓力的物件後,請開始分析根本原因。

2.診斷記憶體空間壓力熱點

選取時間軸範圍,以便視覺化呈現物件分布狀況和各物件占用的空間大小。

視覺化呈現物件分布狀況和各物件占用空間大小
圖7.記憶體分析器顯示選定時間軸中,物件分布的狀況和占用空間大小。

這些資料的分類方式有很多種。以下各節將以案例說明,如何用不同檢視方式來協助您分析問題。

依類別來編排

當您想搜尋會產生物件的特定類別,依類別來編排的方式將展現其實用之處。而這些物件,往往是存於快取或在記憶池中被反覆使用。

舉例來說,假設您看到某個應用程式每秒可建立 2,000 個「Vertex」類別的物件。這會讓需要分配的總物件數每秒增加 2,000 個,且您會看到依照類別區分的狀況。是否應該重複使用這類物件,以避免產生垃圾資訊?如果答案為「是」,可能會需要導入記憶池。

依呼叫堆疊來編排

若有一熱門路徑常需分配記憶體空間 (例如位於一迴圈中或有一特定功能需分配好幾項工作),運用呼叫堆疊來編排將會有很好的效果。依呼叫堆疊來檢視,將可查看分配熱點。

淺層大小與保留大小

淺層大小只會追蹤物件本身占用的記憶體,因此最適合追蹤主要由原始物件組成的簡易類別。

保留大小會顯示以下兩者的加總:該物件直接占用的記憶體空間、其他被該物件單獨引用的相關物件所占用的記憶體空間。由於需要考慮其他物件的占用量,而不單純只有原始空間欄位。在追蹤複雜物件造成的記憶體壓力時,參考保留大小較為適合。如要取得這個數值,請使用記憶體分析器建立記憶體傾印。曾經堆積的物件將會顯示出來。

完整記憶體傾印
圖8.您可以隨時在記憶體分析器的工具列中按一下「Dump Java heap」(傾印 Java 堆積) 按鈕,來建立記憶體傾印。

以欄位的格式新增
圖 9. 建立記憶體傾印時將顯示一欄位,呈現堆積部分的物件配置。

3.測定最佳化的影響

垃圾資訊的收集狀況是一項易於評估的記憶體最佳化改善項目。當最佳化作業成功釋放記憶體壓力,您應該會看到次數較少的垃圾收集 (GC)。如要進行評估,請在分析器時間軸上測量垃圾資訊收集之間的間隔時間長度。記憶體最佳化過後,您應該會發現垃圾資訊收集之間的間隔時間較長。

這些記憶體改善的最終影響如下:

  • 只要記憶體並非長期受到過大的壓力,該應用程式就比較不會因為記憶體空間不足等問題而屢次被系統強行中止。
  • 減少垃圾資訊收集的次數可以改善資源浪費的相關指標。原因是垃圾資訊收集會導致 CPU 資源的爭搶,同時進行可能造成算繪工作被迫延後。