Android性能優(yōu)化工具:Systrace

一、Systrace概述

Systrace是一個(gè)平臺(tái)提供的工具,可以記錄設(shè)備活動(dòng)。它將來(lái)自Android內(nèi)核的數(shù)據(jù)(例如CPU調(diào)度程序,磁盤(pán)活動(dòng)和應(yīng)用程序線程)組合起來(lái)生成一個(gè)報(bào)告。該報(bào)告可幫助您改善您的應(yīng)用或游戲的性能。

Systrace報(bào)告如圖所示:


Systrace.png

此報(bào)告提供了Android設(shè)備在給定時(shí)間段內(nèi)的系統(tǒng)進(jìn)程的總體情況。該報(bào)告還檢查捕獲的跟蹤信息,以突出顯示它所觀察到的問(wèn)題,例如UI 卡頓或高功耗

Systrace工具不會(huì)收集有關(guān)應(yīng)用程序進(jìn)程中代碼執(zhí)行的信息。有關(guān)應(yīng)用程序正在執(zhí)行的方法以及它使用的CPU資源的更多詳細(xì)信息,請(qǐng)使用Android Studio中的CPU Profiler。您還可以 使用CPU Profiler 生成跟蹤日志并導(dǎo)入和檢查它們。

二、在命令行上捕獲

systrace命令調(diào)用Systrace工具,該工具能夠在系統(tǒng)級(jí)別收集所有進(jìn)程的運(yùn)行數(shù)據(jù)。

下面介紹如何從命令行生成Systrace報(bào)告。

要運(yùn)行systrace,請(qǐng)完成以下步驟:

  1. 下載并安裝最新的Android SDK工具

  2. 安裝Python并設(shè)置環(huán)境變量。

  3. 使用USB調(diào)試連接將運(yùn)行Android 4.3(API級(jí)別18)或更高版本的設(shè)備。

systrace命令在Android SDK Tools包中提供,位于android-sdk/platform-tools/systrace/

要為app生成HTML報(bào)告,您需要使用以下語(yǔ)法從命令行運(yùn)行systrace

$ python systrace.py [options] [categories]

例如,使用以下命令記錄設(shè)備活動(dòng)并生成一個(gè)名為mynewtrace.html的報(bào)告

$ python systrace.py -o mynewtrace.html

若沒(méi)指定任何類別或者選項(xiàng),systrace 會(huì)生成一份報(bào)告,包括所有可用的種類,同時(shí)使用默認(rèn)的設(shè)置。

通用的選項(xiàng)

通用選項(xiàng) 描述
-h 或 - -help 顯示幫助信息
-l 或 --list-categories 列出所連設(shè)備可用的 tracing 種類
$ python systrace.py -l
         gfx - Graphics
       input - Input
        view - View System
     webview - WebView
          wm - Window Manager
          am - Activity Manager
          sm - Sync Manager
       audio - Audio
       video - Video
      camera - Camera
         hal - Hardware Modules
         res - Resource Loading
      dalvik - Dalvik VM
          rs - RenderScript
      bionic - Bionic C Library
       power - Power Management
          pm - Package Manager
          ss - System Server
    database - Database
     network - Network
         adb - ADB
    vibrator - Vibrator
        aidl - AIDL calls
         pdx - PDX services
       sched - CPU Scheduling
        freq - CPU Frequency
        idle - CPU Idle
        disk - Disk I/O
        sync - Synchronization
  memreclaim - Kernel Memory Reclaim
  binder_driver - Binder Kernel driver
  binder_lock - Binder global lock trace

命令和命令選項(xiàng)

命令和選項(xiàng) 描述
-o file 將 trace 的網(wǎng)頁(yè)報(bào)告寫(xiě)到指定的文件中。若未指定該選項(xiàng),systrace 會(huì)保存報(bào)告至與 systrace.py 相同的目錄下,同時(shí)命名 trace.html
-t N 或 - -time=N Trace 設(shè)備活動(dòng)的 N 秒時(shí)間。若未指定該選項(xiàng),命令行中,通過(guò)敲 Enter 回車鍵來(lái)終止 trace 進(jìn)程
-b N 或 - -buf-size=N 使用 N 千字節(jié)的 trace 緩沖區(qū)大小。這個(gè)選項(xiàng)可以限制在 trace 期間總共收集數(shù)據(jù)的大小
-k functions 或 - -ktrace=functions Trace 指定內(nèi)核方法的活動(dòng),指定于逗號(hào)分隔的列表
-a app-name或 - -app=app-name 追蹤應(yīng)用包名,用逗號(hào)分隔
--from-file=file-path 從一份文件里創(chuàng)建交互式的網(wǎng)頁(yè)報(bào)告,如從包括原始 trace 數(shù)據(jù)的 TXT 文件,而不是運(yùn)行著動(dòng)態(tài)的 trace
-e device-serial或 - -serial=device-serial 根據(jù)設(shè)備的 serial number,在指定連接的設(shè)備上執(zhí)行 trace
categories 指定跟蹤的類型,例如gfx用于呈現(xiàn)圖形的系統(tǒng)進(jìn)程。

三、設(shè)備上捕獲

Android 9 (API level 28)或更高版本的手機(jī)設(shè)備上會(huì)有一個(gè)App可以調(diào)用系統(tǒng)的tracing,這個(gè)app跟systrace命令行的功能相似。

系統(tǒng)的 Tracing app 允許你使用快捷設(shè)置記錄system trace或者再app內(nèi)使用菜單設(shè)置

(1)開(kāi)啟快捷設(shè)置

開(kāi)啟快捷設(shè)置.png

如果您是第一次在測(cè)試設(shè)備上使用system trace,或者如果在設(shè)備的“ 快速設(shè)置”面板中沒(méi)有看到 錄制跟蹤記錄,請(qǐng)完成以下設(shè)置步驟:

  1. 啟用開(kāi)發(fā)者選項(xiàng)
  2. 打開(kāi)開(kāi)發(fā)者選項(xiàng)設(shè)置界面
  3. 調(diào)試部分選擇系統(tǒng)跟蹤將會(huì)打開(kāi)System Tracing app
  4. 在app設(shè)置頁(yè)面中,開(kāi)啟顯示快捷設(shè)置圖塊錄制跟蹤記錄的圖塊將會(huì)出現(xiàn)在上面的設(shè)置面板中
    System Tracing app.png

(2)使用System trace App捕獲trace

  1. 點(diǎn)擊錄制跟蹤記錄快捷按鈕
    錄制跟蹤記錄.png
  2. 錄制完成后點(diǎn)擊通知欄停止跟蹤


    停止錄制.png
  3. 點(diǎn)擊通知欄后會(huì)彈出分享

(3)使用ADB下載報(bào)告
可以使用ADB從設(shè)備中提取系統(tǒng)跟蹤。將記錄跟蹤的設(shè)備連接到開(kāi)發(fā)計(jì)算機(jī),然后在終端窗口中運(yùn)行以下命令:

cd /path-to-traces-on-my-dev-machine && \
  adb pull /data/local/traces/ .

通過(guò)ADB導(dǎo)出的報(bào)告文件是.ctrace文件,可以通過(guò)命令生成HTML報(bào)告

systrace --from-file trace-file-name .ctrace

三、自定義trace

Android 4.3 (API level 18) 以及更高版本可以使用 Trace 類中的方法來(lái)添加自定義trace

注意:當(dāng)beginSection()被調(diào)用多次時(shí),endSection()僅結(jié)束最近調(diào)用的 beginSection()方法。因此,對(duì)于嵌套調(diào)用(例如以下代碼段中的調(diào)用),請(qǐng)確保每個(gè)beginSection()與 endSection()成對(duì)調(diào)用。此外,不能調(diào)用beginSection()一個(gè)線程并從另一個(gè)線程結(jié)束它; 你必須在同一個(gè)線程上調(diào)用這兩個(gè)方法。

public class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Trace.beginSection("MyAdapter.onCreateViewHolder");
        MyViewHolder myViewHolder;
        try {
            myViewHolder = MyViewHolder.newInstance(parent);
        } finally {
            // In try and catch statements, always call "endSection()" in a
            // "finally" block. That way, the method is invoked even when an
            // exception occurs.
            Trace.endSection();
        }
        return myViewHolder;
    }

   @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        Trace.beginSection("MyAdapter.onBindViewHolder");
        try {
            try {
                Trace.beginSection("MyAdapter.queryDatabase");
                RowItem rowItem = queryDatabase(position);
                dataset.add(rowItem);
            } finally {
                Trace.endSection();
            }
            holder.bind(dataset.get(position));
        } finally {
            Trace.endSection();
        }
    }
}

四、Systrace報(bào)告

Systrace會(huì)產(chǎn)出一個(gè)HTML報(bào)告
(1) 快捷鍵
分析trace.html圖形信息之前,先了解下快捷鍵 點(diǎn)擊瀏覽器界面上右上角“?”,可以查看到各個(gè)快捷鍵提示

  1. 導(dǎo)航
導(dǎo)航操作 作用
w 放大,[+shift]速度更快
s 縮小,[+shift]速度更快
a 左移,[+shift]速度更快
d 右移,[+shift]速度更快
  1. 快捷操作
常用操作 作用
f 放大當(dāng)前選定區(qū)域(放大選定的一塊)
m 標(biāo)記當(dāng)前選定區(qū)域(可以顯示時(shí)間長(zhǎng)度)
v 高亮****VSync****(所在的一幀)
g 切換是否顯示60hz的網(wǎng)格線(同上)
0 恢復(fù)trace到初始態(tài),這里是數(shù)字0而非字母o(縮小到初始)
h 切換是否顯示詳情
/ 搜索關(guān)鍵字
enter 顯示搜索結(jié)果,可通過(guò)← →定位搜索結(jié)果
` 顯示/隱藏腳本控制臺(tái)
? 顯示幫助功能

(2) trace圖結(jié)構(gòu)

systrace.png

  1. Kernel
    (上圖為四核CPU)顯示每個(gè)CPU各自執(zhí)行的系統(tǒng)方法或自定義trace塊,以及占據(jù)的時(shí)間長(zhǎng)度
  2. SurfaceFlinger
    surfaceFilnger,進(jìn)程id為118,顯示系統(tǒng)方法以及占據(jù)的時(shí)間長(zhǎng)度
  3. com.android.janktown
    應(yīng)用進(jìn)程,進(jìn)程id為13409,顯示應(yīng)用進(jìn)程內(nèi)各個(gè)線程等信息
    每個(gè)線程有顏色表示各自不同的狀態(tài):
    灰色:正在休眠。
    藍(lán)色:可運(yùn)行(它可以運(yùn)行,但是調(diào)度程序尚未選擇讓它運(yùn)行)。
    綠色:正在運(yùn)行(調(diào)度程序認(rèn)為它正在運(yùn)行)。
    紅色:不可中斷休眠(通常在內(nèi)核中處于休眠鎖定狀態(tài))。可以指示 I/O 負(fù)載,在調(diào)試性能問(wèn)題時(shí)非常有用。
    橙色:由于 I/O 負(fù)載而不可中斷休眠。

(3) 審查幀和警告
報(bào)告中列出了渲染 UI 幀的每個(gè)進(jìn)程,顯示了時(shí)間線里每幅渲染的幀。綠色幀圈的表明,在要求的 16.6 毫秒內(nèi)保持穩(wěn)定的 60 幀/秒渲染幀像;黃色或紅色幀圈的表明,渲染幀像時(shí)花費(fèi)了超過(guò) 16.6 毫秒。
注意,在 Android 5.0 (API level 21) 及更高的設(shè)備上,渲染幀像的工作被分隔于 UI 主線程和渲染線程。以前的版本,創(chuàng)建幀像的工作都在 UI 主線程完成。

點(diǎn)擊幀圈可以高亮化,提供系統(tǒng)完成渲染幀像額外的信息,包括警告。它也展示渲染幀像時(shí)系統(tǒng)正在執(zhí)行的方法,因此可以根據(jù)這些方法來(lái)找出 UI 卡頓的原因。選擇有問(wèn)題的幀,trace 報(bào)告下面會(huì)展示問(wèn)題詳情的一個(gè) alert。


alert.png

上圖中顯示的Alert顯示出卡頓的主要問(wèn)題是在ListView回收和重新綁定中花費(fèi)了太多的時(shí)間。其中有相關(guān)事件的鏈接可以解釋更多關(guān)于系統(tǒng)在這段時(shí)間內(nèi)正在做什么的事情。
要看 trace 中工具發(fā)現(xiàn)的 alert,以及設(shè)備觸發(fā)每個(gè)警告的次數(shù),可以點(diǎn)擊右上邊上的 Alerts tab。Alerts 欄可以顯示 trace 里發(fā)生的每一個(gè)問(wèn)題和它們導(dǎo)致卡頓的頻次。


alert.png

若看到 UI 主線程中做了太多的工作,需要我們自己找出消耗 CPU 時(shí)間的那些方法,方法之一是在認(rèn)為導(dǎo)致性能瓶頸的地方,添加 trace 標(biāo)記,來(lái)查看 trace 中出現(xiàn)的調(diào)用方法。若不確定哪些方法或許導(dǎo)致 UI 主線程的瓶頸,使用 Android Studio 內(nèi)置的 CPU profiler,或生成的 trace 日志,然后使用 Traceview 查看。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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