Android效能分析工具systrace使用
Android效能分析工具systrace的使用,能根據需要抓取trace。
瞭解trace檔案中資料的含義,能分析簡單的效能問題。
1、systrace簡介
systrace是Android4.1版本之後推出的,對系統Performance分析的工具。
systrace的功能包括跟蹤系統的I/O操作、核心工作佇列、CPU負載以及Android各個子系統的執行狀況等。在Android平臺中,它主要由3部分組成:
-
核心部分:Systrace利用了Linux Kernel中的
ftrace
功能。所以,如果要使用systrace的話,必須開啟kernel中和ftrace -
資料採集部分:Android定義了一個Trace類。應用程式可利用該類把統計資訊輸出給ftrace。同時,Android還有一個
atrace
程式,它可以從ftrace中讀取統計資訊然後交給資料分析工具來處理。 -
資料分析工具:Android提供一個
systrace.py
(python指令碼檔案,位於Android SDK目錄/sdk/platform-tools/systrace
中,其內部將呼叫atrace程式)用來配置資料採集的方式(如採集資料的標籤、輸出檔名等)和收集ftrace統計資料並生成一個結果網頁檔案供使用者檢視。
簡單來說,當機器以
Systrace 是用來收集系統和應用的資料資訊和一些中間生成資料的細節,在Android 4.1系統和4.1之後的系統。
Systrace在一些分析顯示的問題上特別有用,如應用畫圖慢,顯示動作或動畫時變形。
2、抓取systrace
進入Android/Sdk/platform-tools/systrace目錄下
python systrace.py -b 8000 -t 5 -o systrace.html
Google Chrome瀏覽器可以開啟systrace,如果打不開,可以瀏覽器輸入chrome://tracing/
,然後load systrace。
(1)指令碼命令的option
options |
描述 |
---|---|
-o < FILE > |
輸出的目標檔案 |
-t N, –time=N |
執行時間,預設5s |
-b N, –buf-size=N |
buffer大小(單位kB),用於限制trace總大小,預設無上限 |
-k < KFUNCS >,–ktrace=< KFUNCS > |
追蹤kernel函式,用逗號分隔 |
-a < APP_NAME >,–app=< APP_NAME > |
追蹤應用包名,用逗號分隔 |
–from-file=< FROM_FILE > |
從檔案中建立互動的systrace |
-e < DEVICE_SERIAL >,–serial=< DEVICE_SERIAL > |
指定裝置 |
-l, –list-categories |
列舉可用的tags |
(2) 在app新增自己的systrace log
說明1:-o trace輸出的檔案路徑
說明2:--time 配置抓取systrace的時間,通常設定5秒,並在5秒內重現問題,時間太短會導致問題重現時沒有被抓到,時間太長會導致JavaHeap不夠而無法儲存,因此在能抓到問題點的情況下,時間越小越好。
說明3:--buf-size Buffer Size是儲存systrace的size,同樣的,太小會導致資訊丟失,時間太長會導致Java Heap不夠而無法儲存,建議20480。
說明4:如果使用者有自己在應用程式中加入自己的systrace log,如下:
Trace.beginSection("newInstance");
Trace.endSection("newInstance");
那麼此處必須選擇這個應用對應的程序名字,否則新加的systrace log不會被抓到。
在一些方法里加入trace 方便自己 跟蹤除錯 , 如下:
Trace.traceBegin("performTraversals");
try {
……
} finally {
Trace.traceEnd();
}
需要保證 traceBegin 與 traceEnd 一定要成對出現。 並且一定要在同一個執行緒裡面。
加入trace的好處在於,生成的trace檔案中,會在跟蹤的程式碼段執行對應時間軸區間打上一個tag標記(比如上例中的performTraversals)
如果在程式碼中加入了trace,在生成trace檔案時,必須指定程序為trace所在的程序。
3、systrace.html分析
3.1 trace圖結構
3.1.1、顏色釋義
在程序的上面有一條很細的進度條,包含了該執行緒的狀態:
灰色: 睡眠。
藍色: 可以執行(它可以執行,但還未被排程執行)。
綠色: 正在執行(排程程式認為它正在執行)。
紅色: 不間斷的睡眠(通常發生在核心鎖上), 指出I / O負載,對於效能問題的除錯非常有用
橙色: 由於I / O負載導致的不間斷睡眠。
要檢視不間斷睡眠的原因(可從sched_blocked_reason跟蹤點獲取),請選擇紅色不間斷睡眠切片。
------------------------------------------------------------------------------------------------------------------------
同一個程序內按執行緒進行縱向拆分,每個執行緒記錄自己的工作。分別以包名為標識。每個應用程序都會包含其中所有執行緒的記錄訊號,可以看到從InputEvent到RenderThread都有。
除了程序和執行緒執行資訊,還有兩個重要資訊:
3.1.2、Frame(例:UI Performance)
每個app都有一行專門顯示frame,每一幀就顯示為圓圈,正常繪製是1秒60幀,大約一幀16.6毫秒,在這個值以下是正常顏色綠色,如果超過它就會變成紅色、黃色。非綠色的都說明有問題。這時需要通過’w’鍵放大那一幀,然後按‘m’鍵高亮,進一步分析問題。
以分析UI Performance為例:
對於Android 5.0(API level 21)或者更高的裝置,該問題主要聚焦在UI Thread
和Render Thread
這兩個執行緒當中。對於更早的版本,則所有工作在UI Thread
。
3.1.3、Alerts
Systrace能自動分析trace中的事件,並能自動高亮效能問題作為一個Alerts,建議除錯人員下一步該怎麼做。
比如對於丟幀,點選黃色或紅色的Frames圓點便會有相關的提示資訊;另外,在systrace的最右上方,有一個Alerts tab可以展開,這裡記錄著所有的的警告提示資訊。
3.1.4、使用alert和frame分析
(1)當我們點選了Alerts或者點選右邊的Alerts列表中的任何一點我們可以看到在介面的最底部會相對應的優化提示以及可能會出現優化的視訊教程連結。
比如上面的提示說你View的draw繪製花的時間太長了,然後我們可以根據Description來很明白的看到提示的內容是什麼。
(2)然後我們可以點選一塊Frames中的F來檢視,同樣的它會生成一份跟Alerts類似的報告結果並放在介面的最底端。
(3)可以通過按下m鍵檢視這一幀到下一幀所花費的時間以及哪個方法被呼叫的最長。看到時間>16.6ms,系統要求UI的60fps水準所以系統會報出黃色的警告。照樣我們從Description中可以讀出到底是哪裡出了問題。
Description :
-
ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.
可以看出來系統提示你在getView中花費了太多時間沒能很有效的複用機制。我們就能順著這條路去找介面的程式碼哪裡出現了不足從而優化完善。
(4)Alerts和Frames兩欄,它們展示了通過手機來的資料而生成出來的視覺化分析結果。選擇最上方的alerts:
這個警告指出了,有一個View#draw()方法執行了比較長的時間。可以在下面看到問題的描述,連結,甚至是相關的視訊。下面我們看Frames這一行,可以看到這裡展示了被繪製出來的每一幀,並且用綠、黃、紅三顏色來區分它們在繪製時的效能。
(5)frame一欄(點選右側Alert type的Scheduling delay):在下方顯示欄,我們看到了與這一幀所相關的一些警告。在這三個警告中,有一個是我們上面所提到的(View#draw())。接下來我們在這一幀處放大並在下方展開“Inflation during ListView recycling”這條警告:
可以看到警告部分的總耗時,32毫秒,遠高於了我們對保障60fps所需的16毫秒繪製時間。同時還有更多的ListView每個條目的繪製時間,大約是6毫秒每個條目,總共五個。而Description描述項中的內容會幫助我們理解問題,甚至提供問題的解決方案。
(6)可以在“inflate”(某個函式方法)這一個塊區處放大,並且觀察到底是哪些View在被填充過程中耗時比較嚴重。
在選擇了某一幀之後,按“m”鍵來高亮這一幀,並且在上方看到了這一部分的耗時,如圖,我們看到了這一陣的繪製總共耗時超過19毫秒。而當我們展開這一幀唯一的一個警告時,我們發現了“Scheduling delay”這條錯誤。
Scheduling delay(排程延遲)的意思就是一個執行緒在處理一塊運算的時候,在很長一段時間都沒有被分配到CPU上面做運算,從而導致這個執行緒在很長一段時間都沒有完成工作。我們選擇這一幀中最長的一塊,從而得到更加詳細的資訊:
在紅框區域內,“Wall duration”,他代表著這一區塊的開始到結束的耗時。
CPU Duration一項中顯示了實際CPU在處理這一區塊所消耗的時間。
很顯然,兩個時間的差距還是非常大的。整個區塊耗時18毫秒,而在這之中CPU只消耗了4毫秒的時間去運算。
這時候應該到最上面看Kernel中CPU在做什麼操作。
(7)在這一幀中選擇一個CPU,檢視執行的程序和執行緒。
可能會由於另外一個程式佔用CPU,導致了我們的程式未能獲得足夠的CPU資源。
但是這種情況其實是暫時的,因為被其他後臺應用佔用CPU的情況並不多見,但仍有其他應用的執行緒或是主執行緒佔用CPU。
3.2、systrace重點分析部分(由上往下)
(1)CPU
(2)在SurfaceFlinger上面有一個SurfaceView顯示buffer的數量
(3)VSYNC訊號(一幀16.67ms)分為:
VSYNC-app
VSYNC-sf
相互錯位,並且SF進行影象混合的時候總是在每幀的最開始。不能超過一幀。
(4)SurfaceFlinger
在每幀的最開始,包含SurfaceFlinger模組呼叫的各個函式。
主要有:
acquireBuffer從BufferQueue申請buffer
releaseBuffer 釋放buffer返回到BufferQueue
PS:如果Buffer數量過多,可能是釋放buffern之前呼叫到display模組的函式停滯過久。
(5)app的繪製
例如對手機camera進行拍照時抓取systrace,繪製的app就是camera。
繪製也是在一幀的開始(VSYNC-app)。
繪製中包含呼叫的各個函式。
主要有:
dequeueBuffer從BufferQueue申請buffer
queueBuffer返回buffer到BufferQueue
(6)LCD(HWC、display..)
顯示模組,在app的下面,一般為UI thread,包含在SF進行影象混合後,將buffer傳遞到這個模組。
3.2.1、app、sf、顯示三者的關係:
在app的一幀中繪製好後,將資訊傳遞到SF;
在VSYNC-sf下一幀開始時,SF進行影象混合;
在SF影象混合後進行LCD顯示(可能在SF混合的過程中就已經呼叫到顯示模組的函式,因此時間上可能會有交叉。)
3.2.2、一個持續定期的工作負載的階段
例如TouchLatency,UI管道,通常包含以下階段:
-
SurfaceFlinger中的EventThread喚醒了應用程式UI執行緒,表明現在是渲染新幀的時候了。
-
應用程式使用CPU和GPU資源在UI執行緒,RenderThread和hwuiTasks中渲染幀。這部分暫UI的大部分。
-
應用程式通過binder將繪製好的幀傳送到SurfaceFlinger並進入睡眠狀態。
-
SurfaceFlinger中的第二個EventThread喚醒SurfaceFlinger來觸發組合和顯示輸出。如果SurfaceFlinger確定沒有任何工作要完成,它將返回睡眠狀態。
-
SurfaceFlinger通過HWC / HWC2或GL處理組合。 HWC / HWC2組合更快,更低的功耗,但會受到SOC的限制。這一步通常需要4-6ms,但是可以與步驟2重疊,因為Android應用程式總是三重緩衝。 (雖然應用程式總是三重緩衝,但在SurfaceFlinger中只能有一個待處理幀,因此和雙重快取差不多。)
-
SurfaceFlinger通過供應商驅動程式排程最終輸出,並返回睡眠狀態,等待EventThread喚醒。
4、systrace操作快捷鍵
4.1、導航
導航操作 |
作用 |
---|---|
w |
放大,[+shift]速度更快 |
s |
縮小,[+shift]速度更快 |
a |
左移,[+shift]速度更快 |
d |
右移,[+shift]速度更快 |
4.2、快捷操作
常用操作 |
作用 |
---|---|
f |
放大當前選定區域(放大選定的一塊) |
m |
標記當前選定區域(可以顯示時間長度) |
v |
高亮VSync(所在的一幀) |
g |
切換是否顯示60hz的網格線(同上) |
0 |
恢復trace到初始態,這裡是數字0而非字母o(縮小到初始) |
一般操作 |
作用 |
---|---|
h |
切換是否顯示詳情 |
/ |
搜尋關鍵字 |
enter |
顯示搜尋結果,可通過← →定位搜尋結果 |
` |
顯示/隱藏指令碼控制檯 |
? |
顯示幫助功能 |
4.3、模式切換(小功能框)
-
Select mode: 雙擊已選定區能將所有相同的塊高亮選中;(對應數字1)
-
Pan mode: 拖動平移檢視(對應數字2)
-
Zoom mode:通過上/下拖動滑鼠來實現放大/縮小功能;(對應數字3)
-
Timing mode:拖動來建立或移除時間視窗線。(對應數字4)
可通過按數字1~4,用於切換滑鼠模式; 另外,按住alt鍵,再滾動滑鼠滾輪能實現放大/縮小功能。