Android性能優化--Systrace工具

Systrace

Systrace是一個平臺提供的工具,可以在很短的時間內記錄設備活動。該工具生成一個報告,該報告結合了Android內核中的數據,例如CPU調度程序,磁盤活動和應用程序線程。報告可以確定如何最好地改善應用或游戲的性能。

chrome查看trace報告

報告提供了Android設備在給定時間段內的系統進程的總體情況。該報告還檢查捕獲的跟蹤信息,以突出顯示它所觀察到的問題,例如UI jank或高功耗。

通過sdk自帶的腳本工具獲取想要的報告,報告只能用Chrome瀏覽器分析查看

獲取Systrace報告文件

使用sdk的工具生成報告文件
工具:/sdk/platform-tools/systrace

systrace腳本工具

可以通過設定腳本參數得到自己想要的報告內容

通過命令查看連接設備所支持的類型列表
python systrace.py --list-categories
可以看到可以分析的模塊十分全面從硬件到軟件、從底層到上層app、從view到渲染引擎基本全覆蓋,配合上Profiler、MAT、hprof-conv、Hierarchy view、OverDraw工具可謂是一劍在手天下我有

image.png

獲取報告的命令參數
./systrace.py -h

Commands options 描述
-h --help 顯示幫助信息
-l --list-categories 列出所連接設備可用的跟蹤類別
-o file 將HTML跟蹤報告寫入指定的文件。如果未指定此選項,systrace請將報告保存到與其相同的目錄中并為其命名。 systrace.pytrace.html
-t N --time=N 跟蹤設備活動N秒。如果未指定此選項,則systrace提示您通過從命令行按Enter鍵來結束跟蹤。
-b N --buf-size=N 使用N千字節的跟蹤緩沖區大小。此選項允許您限制跟蹤期間收集的數據的總大小。
-k functions --ktrace=functions 跟蹤以逗號分隔的列表中指定的特定內核函數的活動。
-a app-name --app=app-name 啟用應用程序的跟蹤,指定為以逗號分隔的進程名稱列表 。應用程序必須包含來自Trace類的跟蹤檢測調用 。每當您分析應用程序庫時,都應指定此選項,例如 RecyclerView,包括跟蹤檢測調用,這些調用在啟用應用程序級跟蹤時提供有用信息。有關更多信息,請轉到有關如何檢測應用程序代碼的部分。
--from -file=file-path 從文件創建交互式HTML報告,例如包含原始跟蹤數據的TXT文件,而不是運行實時跟蹤。
-e device-serial --serial=device-serial 在特定連接設備上進行跟蹤
categories 包括您指定的系統進程的跟蹤信息,例如gfx用于呈現圖形的系統進程。您可以systrace使用該-l命令運行以查看所連接設備可用的服務列表。
--walt WALT trace options 測量手機和計算機上物理傳感器和輸出的延遲

獲取報告
無時間限制,需要enter鍵開始
./systrace.py -o trace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res
加時間參數
./systrace.py -o trace.html -t 12 sched freq idle am wm gfx view binder_driver hal dalvik camera input res
完成后使用chrome打開得到的文件即可

獲取報告的命令執行,file路徑為報告文件路徑

Android9以上版本也可以通過開發者模式獲取

次方式不推薦使用


打開系統跟蹤

開啟記錄
停止記錄
分享記錄文件

通過消息或通過ADB共享跟蹤時,報告本身駐留在.ctrace文件中。使用此文件,可以生成跟蹤的HTML報告。為此,請在終端窗口中運行以下命令:

cd / path-to-traces-on-my-dev-machine && \
systrace --from-file trace-file-name .ctrace

但是需要systrace命令行程序

報告分析

Systrace生成包含一系列部分的輸出HTML文件。該報告列出了每個進程的線程。如果給定線程呈現UI幀,則報告還指示沿時間線的呈現幀。當在報告中從左向右移動時,時間會向前傳遞。

報告從上到下包含以下部分

  • UI交互活動
    第一部分包含表示應用或游戲中特定用戶交互的條形圖,例如點擊設備屏幕。這些相互作用充當有用的時間標記
    UI交互活動
  • CPU活動
    顯示了表示每個CPU中的線程活動的條形圖。條形圖顯示所有應用程序(包括您的應用程序或游戲)的CPU活動。

折疊的CPU活動部分的示例


折疊圖

CPU活動部分是可擴展的,允許您查看每個CPU的時鐘頻率


CPU活動(展開視圖),顯示Systrace報告中的CPU時鐘頻率
  • 系統事件
    直方圖顯示特定的系統級事件,例如紋理計數和特定對象的總大小。
    系統級事件

值得仔細檢查的直方圖是標記為SurfaceView的直方圖。計數表示已傳遞到顯示管道并等待在設備屏幕上顯示的組合幀緩沖區的數量。由于大多數設備都是雙緩沖或三緩沖,因此該計數幾乎總是0,1或2。

描述Surface Flinger過程的其他直方圖,包括VSync事件和UI線程交換工作,如下圖


Systrace報告中的Surface Flinger示例圖
  • 顯示框架
    顯示框架

這一部分,通常是報告中最多的部分,描繪了一條彩色線條,后面是成堆的條形圖。這些形狀表示已創建的特定線程的狀態和幀堆棧。

UI線程或應用程序或游戲通常運行的主線程始終顯示為第一個線程。

幀堆棧信息

每堆條形圖上方的多色線表示特定線程隨時間變化的狀態集。該行的每個部分可以包含以下顏色之一:

綠色:Running
線程正在完成與進程相關的工作或正在響應中斷。
藍色:Runnable
線程可以運行但當前沒有安排。
白色:Sleeping
線程沒有工作要做,可能是因為線程在互斥鎖上被阻塞。
橙色:Uninterruptable sleep(不間斷的睡眠)
線程在I / O上被阻塞或等待磁盤操作完成。
紫色:Interruptable sleep(可以中斷睡眠)
線程在另一個內核操作(通常是內存管理)上被阻塞。

  • 報告分析操作快捷鍵
key 描述
W 放大時間軸
A 在跟蹤時間線上左移
S 縮小時間軸
D 在跟蹤時間軸上向右平移
E 將跟蹤時間軸置于當前鼠標位置的中心
M 選中當前幀
1 將當前活動的選擇模型更改為“選擇”模式。對應于鼠標選擇器工具欄中顯示的第一個按鈕
2 將當前活動的選擇模型更改為“平移”模式。對應于鼠標選擇器工具欄中顯示的第二個按鈕
3 將當前活動的選擇模型更改為“縮放”模式。對應于鼠標選擇器工具欄中顯示的第3個按鈕
4 將當前活動的選擇模型更改為“計時”模式。對應于鼠標選擇器工具欄中顯示的第4個按鈕
G 在當前所選任務的開頭顯示網格
Shift + G 在當前所選任務的末尾顯示網格
左鍵 在當前選定的時間軸上選擇上一個事件
右鍵 選擇當前所選時間軸上的下一個事件

自定義systrace數據獲取

以上數據默認僅在系統級別向顯示有關進程的信息,因此有時很難知道應用程序或游戲的哪些方法在給定時間相對于系統事件執行。

Android平臺提供了一個trace API,可以使用它來標記特定的代碼段。如果捕獲應用程序“debug”版本的新系統跟蹤并包含該-a選項,如下面的代碼段所示,這些自定義事件將顯示在Systrace報告中:

python systrace.py -a com.zerone.qrcode -b 16384 -o my_systrace_report.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res 

java 層code
堆棧的每個級別代表為應用或游戲定義beginSection()的自定義跟蹤事件的調用或開始

  • Trace.beginSection(String sectionName)Trace.endSection()需要成對出現
  • 為保證每個 Trace.beginSection(String sectionName) 都會有對應的 Trace.endSection(),建議使用 try {……} finally {……}
  • 如果在 Trace.endSection()之前有多個 Trace.beginSection(String sectionName),Trace.endSection()會匹配離它最近的一個未匹配過的 Trace.beginSection(String sectionName)
  • Trace.beginSection(String sectionName)Trace.endSection()需要在同一線程中

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 {
            //在try和catch語句中,總是在a中調用“endSection()”
            //“終于”阻止。這樣,即使在a時也調用該方法
            //發生異常。
            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();
        }
    }
}

Native層code
Android 6.0(API級別23)及更高版本支持native trace API,trace.h將跟蹤事件寫入系統緩沖區,然后使用Systrace進行分析。此API的常見用例包括觀察特定代碼塊執行的時間以及將代碼塊與不良系統行為相關聯的時間。

要定義應用或游戲中本機代碼中發生的自定義事件,請完成以下步驟:
1、定義用于捕獲游戲中自定義事件的ATrace函數的函數指針,如以下代碼段所示:

#include <android/trace.h>
#include <dlfcn.h>

void *(*ATrace_beginSection) (const char* sectionName);
void *(*ATrace_endSection) (void);

typedef void *(*fp_ATrace_beginSection) (const char* sectionName);
typedef void *(*fp_ATrace_endSection) (void);

2、在運行時加載ATrace符號,如以下代碼段所示。通常,在對象構造函數中執行此過程。

//檢索libandroid的句柄。
void *lib = dlopen("libandroid.so", RTLD_NOW || RTLD_LOCAL);

//訪問本機跟蹤功能。
if (lib != NULL) {
   //使用dlsym()防止運行Android 5.1的設備崩潰
    //(API級別22)或更低。
    ATrace_beginSection = reinterpret_cast<fp_ATrace_beginSection>(
        dlsym(lib, "ATrace_beginSection"));
    ATrace_endSEction = reinterpret_cast<fp_ATrace_endSection>(
        dlsym(lib, "ATrace_endSection"));
}

出于安全原因,請dlopen()僅在您的應用或游戲的調試版本中包含調用 。

3、打電話ATrace_beginSection()和 ATrace_endSection()在開始和結束時,分別自定義事件:

#include <android/trace.h>

char *customEventName = new char[32];
sprintf(customEventName, “用戶點擊%s按鈕” , buttonName);

ATrace_beginSection(customEventName);
//您的應用或游戲對按下按鈕的響應。
ATrace_endSection();
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一、Systrace概述 Systrace是一個平臺提供的工具,可以記錄設備活動。它將來自Android內核的數據...
    小村醫閱讀 4,203評論 0 16
  • 文集目錄 ps:喜歡的點贊哦 android性能跟蹤分析工具系列 - 目錄 systrace 案例參考: Syst...
    前行的烏龜閱讀 3,623評論 0 1
  • 1,卡頓的原因 界面繪制:主要原因是繪制的層級深、頁面復雜、刷新不合理,由于這些原因導致卡頓的場景更多出現在UI和...
    dev_journey閱讀 8,771評論 0 5
  • 久違的晴天,家長會。 家長大會開好到教室時,離放學已經沒多少時間了。班主任說已經安排了三個家長分享經驗。 放學鈴聲...
    飄雪兒5閱讀 7,552評論 16 22
  • 創業是很多人的夢想,多少人為了理想和不甘選擇了創業來實現自我價值,我就是其中一個。 創業后,我由女人變成了超人,什...
    亦寶寶閱讀 1,861評論 4 1