Android應用性能優化之分析工具
上一次記錄瞭解決過分繪製的過程,這一次,想先弄清個概念性的東西,就是如何判斷順不暢?
這東西其實最初我本身也以爲有點廢話,用起來會卡就明顯是不暢咯。
但這東西就跟我很想吐槽不少應用同樣,明明那麼卡還放出來同樣的道理。
理論永遠是理論,實踐纔是第一輩子產力。
由於我本身的應用也能感受到卡頓,如今回頭分析,能明白,卡頓永遠不是「用心的程序員」本來的初衷,但不少東西,真心是難言之隱。
知錯就改纔是好人...因此要改,就要知道究竟錯在哪。
一、縱觀全局
對於順暢度的分析,首先要知道一個總體狀況,是局部,仍是全局,這樣在優化上纔能有方向。
若是是局部問題,那就須要仔細分析出具體的相關操做,若是是大致上的問題,那在思考的時候,就須要從總體的實現機制來考慮,有多是實現方式上出現了問題。
在android4.1中,谷歌提供了一個工具來,叫作「
GPU呈現模式分析(Profile GPU rendering)
」,在開啓這個功能後,系統就會記錄保留每一個界面最後128幀圖像繪製的相關時間信息。
若是是在開啓應用後纔開啓此功能,記得先把應用結束後從新啓動。
開啓後操做你須要分析的部分(好比滑動列表之類的),而後執行adb命令
$ adb shell dumpsys gfxinfo com.xxxx.xxx
在執行的結果中,有一塊叫作「Profile data in ms」底下有一堆數據.
Draw:表示在Java中建立顯示列表部分中,OnDraw()方法佔用的時間。
Process:表示渲染引擎執行顯示列表所花的時間,view越多,時間就越長
Execute:表示把一幀數據發送到屏幕上排版顯示實際花費的時間。實際上是實際顯示幀數據的後臺緩存區與前臺緩衝區交換後並將前臺緩衝區的內容顯示到屏幕上的時間。因此這個時間,通常都很短。
PS:View類包含Surface(變量名mSurface),每一個Surface一般對應兩個buffer,一個front buffer, 一個back buffer。(4.1以後是3個,一個前,兩個後)其中,back buffer就是canvas繪圖時對應的bitmap (研究
Android_view_Surface.cpp::lockCanvas)。所以,繪畫老是在back buffer上,須要更新時,則將back buffer和front buffer互換。
Draw + Process + Execute = 完整顯示一幀 ,這個時間要小於16ms才能保存每秒60幀。
將數據複製到excel中(win記得逐列複製,mac下就直接複製過去吧),而後將數據生成「堆積柱形圖」
從圖上看,能看出幾個現象。第一,確實4.1的黃油項目還真的有點做用,每幀的時間控制在16ms左右。第二,有幾幀超過16ms,確實會有丟幀的現象。
看來,頁面的卡頓應該是個別操做的問題。
但這種數據是否還能看出其餘問題呢?
按照3個數據分別標示的內容,理論來說,若是UI線程佔用的時間過長,Draw的時間數據會應該會很長,因此作了個實驗,在UI線程中睡了1S。獲得了下面這個圖。
從圖上看有幾幀Draw部分異常的高就能看出,Draw部分能看出UI線程的大致使用狀況。
固然,其實這個數據主要能看出的是總體狀況,單獨的某個部分跟測試的環境也有很大關係,好比一下2組數據,都是instagram的,一樣的數據,上面是Desire Z 4.1系統,下面是蓋3 4.1系統,在Execute部分,二者有明顯的差距。
二、具體分析
「GPU呈現模式分析」的數據只能說明個現象,好比上面提到的數據,能說明在實際運行中會有短暫的長時間繪製問題。但形成問題的具體緣由並無說明。
並且「GPU呈現模式分析」顯示的是最後128幀的數據,但丟幀也有多是兩幀之間存在長時間的操做而形成的。
因此咱們須要分析幀與幀之間的狀況,才能對所分析應用的總體性能狀況有個更升入的瞭解。
在android中提供了兩個工具來達到這個目的:一、Systrace
(這工具坑的我....等下再吐槽) 二、t
raceview
Systrace是對整個系統進行分析,數據比較準確,固然也包括咱們所要分析的應用。
當這個工具的使用是有條件限制的:
(1)是4.1以後才提供的工具。
(2)手機的內核必定要支持trace(能夠查看是否存在
/sys/kernel/debug/tracing 這個目錄
),因此不少第三方ROM或者三星之類的rom都在內核中remove了這個模塊。模擬器裏面好像也都沒有。[這個坑的我刷了無數多的rom才找到適合的...以前的one x我記得好像也有,這個也間接說明一點,做爲開發者,仍是乖乖的買親兒子好]
Systrace的運行方式有兩種,一種是運行sdk包下的py文件,這種要求的環境配置比較多。另外一種就是在adt下的工具,點擊直接運行。因此下面的使用介紹主要是這種。
在流暢程度的這種特殊分析情景下,咱們通常只關注圖形性能。因此咱們要選擇Graphics和View.還有其餘不少選項,若是是在作音頻處理或者視頻播放的分析測試話,能夠選擇其餘選項。
確認運行以後,滾輪咱們要測試的列表,工具會記錄5秒鐘的數據,以後咱們回獲得一個html頁面。打開後,咱們能看到頁面中顯示了系統中一切運行狀況的概述。
瀏覽的操做時經過WASD來完成,W/S 放大/縮小 A/D 左移/右移
頁面中有個surfaceFlinger, 知道android繪製原理的人應該能明白,這個就是負責繪製Android應用程序UI的服務,因此surfaceFlinger能反應出總體繪製情 況,通常正常狀況都是連續的,若是出現空檔,一種是沒有操做或者滑動到頭,沒東西須要繪製,這種屬於正常,另外一種就是有問題存在,有其餘操做時間過長。
對應所要分析的程序那行,放大後就能看到具體的狀況,點擊後能看到每一個部分所使用的時間。
好比
deliverInputEvent是系統提供的觸摸事件。
performTraversals是開始佈局而且繪畫顯示畫面的過程。
draw是繪畫的過程。
...
對於一個listview,若是deliverInputEvent過長,頗有多是在adapter中的getView方法中處理時間過長致使。
因此經過
Systrace的數據,能夠大致上的發現是否存在性能問題。
但若是要知道具體狀況,就須要用到另一個工具。
traceview
這個工具其實比較簡單,是一個分析器,記錄了應用程序中每一個函數的的執行時間。在DDMS中,選中要分析的進場,點擊
「Start method profiling」(就是右上角有個紅點的圖標)。而後開始操做要分析的應用,而後再次點擊按鈕來中止跟蹤。
而後下面顯示的數據應該挺通俗易懂的。
具體的能夠參見:http://hubingforever.blog.163.com/blog/static/17104057920112825035143/
這裏我想介紹下我使用的一個經驗。
ViewRootImpl.draw(),這個是繪製函數,點擊後,繪製的部分就會被突出出來。從理論上講,只要操做時沒有太多停頓,draw()的圖示應該是較爲連續的。而且要保持順暢,每個draw區域應該在16ms及如下。
因此一旦看到區域有大於16ms的,就能夠認真分析下,看看都作了些什麼操做。從而找到致使繪製時間過長的問題所在。
對於這些工具的使用,雖然很大程度上可以幫助咱們更快的定位到問題之處,但仍是有許多侷限的地方。
若是對android總體系統原理有必定的理解,而且深入知道本身的程序的運轉狀況,這樣分析起來,纔會爐火純青。
以上是我我的的一些見解,但願能幫助到你們,沒寫的太細,夠用就好,由於有些部分,本身也有不少疑問,找到了一堆資料,發現也沒有說明的特別詳細的地方。
如下是參考的一些地方,你們能夠去看看,有些須要走出去(怎麼出去這東西每一個程序員都會吧?):