一、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)告如圖所示:
此報(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)完成以下步驟:
安裝Python并設(shè)置環(huán)境變量。
使用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è)置
如果您是第一次在測(cè)試設(shè)備上使用system trace,或者如果在設(shè)備的“ 快速設(shè)置”面板中沒(méi)有看到 錄制跟蹤記錄,請(qǐng)完成以下設(shè)置步驟:
- 啟用開(kāi)發(fā)者選項(xiàng)
- 打開(kāi)開(kāi)發(fā)者選項(xiàng)設(shè)置界面
- 在
調(diào)試
部分選擇系統(tǒng)跟蹤
將會(huì)打開(kāi)System Tracing app - 在app設(shè)置頁(yè)面中,開(kāi)啟
顯示快捷設(shè)置圖塊
,錄制跟蹤記錄
的圖塊將會(huì)出現(xiàn)在上面的設(shè)置面板中
System Tracing app.png
(2)使用System trace App捕獲trace
- 點(diǎn)擊
錄制跟蹤記錄
快捷按鈕
錄制跟蹤記錄.png -
錄制完成后點(diǎn)擊通知欄停止跟蹤
停止錄制.png - 點(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è)快捷鍵提示
- 導(dǎo)航
導(dǎo)航操作 | 作用 |
---|---|
w | 放大,[+shift]速度更快 |
s | 縮小,[+shift]速度更快 |
a | 左移,[+shift]速度更快 |
d | 右移,[+shift]速度更快 |
- 快捷操作
常用操作 | 作用 |
---|---|
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)
- Kernel
(上圖為四核CPU)顯示每個(gè)CPU各自執(zhí)行的系統(tǒng)方法或自定義trace塊,以及占據(jù)的時(shí)間長(zhǎng)度 - SurfaceFlinger
surfaceFilnger,進(jìn)程id為118,顯示系統(tǒng)方法以及占據(jù)的時(shí)間長(zhǎng)度 - 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顯示出卡頓的主要問(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)致卡頓的頻次。
若看到 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 查看。