使用TraceView+实际案列实战性能分析 找出android app UI卡顿原因
TraceView
- 前言
- UI卡頓
- TraceView
- Debug
- DDMS 工具
- 實例分析
- Profile Panel
前言
最近公司SE拿了一個南京廠家做的一款工程機跟我反映一個問題,說在這個手機上使用公司APP的一個上下翻頁功能的時候,翻頁動作執行的就像慢動作一樣(看下圖);瞬間我特么菊花一緊,居然有這種事,這不能忍啊,同時心中也是一萬只草泥馬奔騰而過,心想:大哥 你又從哪個不知名廠家拿了個手機過來啊,鬼知道他們的手機有沒有問題呢,測試都用了十來臺工程機和市場上的民用手機都沒出現這問題;但是現實是殘酷的,誰讓我是程序猿呢,只能乖乖的去查原因了
這是將翻頁功能單獨做個demo,可以看到翻頁的過程很慢
UI卡頓
ui卡頓應該是程序猿最不想見到的問題了,或者說現象吧,因為這讓用戶很直接的感受到極差的使用體驗,此時用戶的內心OS:這什么垃圾APP啊,做的這么卡;心情好點的可能連帶著手機一起懟,這什么垃圾手機啊,性能這么差;所以在平常開發的時候一定要注意這方面的問題,多做測試,同時多拿一些機型測試,畢竟Android碎片化太嚴重了,隨便一個小廠家都能做個手機出來賣。
一般來說UI卡頓,比如列表卡頓,動畫卡頓,界面切換卡頓,基本上都是因為主線程有耗時操作,影響視圖的連貫展示;而耗時有兩種情況:
- 方法調用次數不多,但是單次執行該方法耗時
- 方法單次執行不耗時,但是調用次數過多導致耗時
開頭也說了,只在這款工程機上出現了翻頁慢的情況,所以第一種情況是不可能了;所以只能考慮第二種情況了,因為第二種情況還是要取決于設備的硬件的,但是想一眼找到哪塊方法耗時真不容易,這時候就要借助工具來幫我們找出到底誰在偷偷的做耗時操作
TraceView
本文要用到的性能分析工具就是TraceView,它是Android平臺的特有的一個用于性能分析的工具,通過圖形化界面的方式展示程序的性能表現,可以具體追蹤到方法級別;TraceView本身是一個數據分析工具,而數據采集需要依靠Debug 類或者 DDMS 工具,兩者用法如下
Debug
假如你明確知道是哪個方法耗時,或者哪個操作耗時,這時候你就可以通過Debug類的API來分析;比如你想測下方法A要消耗多長時間和這段時間內所有線程的執行情況(只有Java線程),那就在方法A的開頭添加Debug.startMethodTracing方法,然后結束時添加Debug.stopMethodTracing方法(想分析Native層的用startNativeTracing方法);這時候會在SD卡根目錄下生成一個dmtrace.trace文件,切記要添加并申請WRITE_EXTERNAL_STORAGE權限,如下
public void onClick(View v) {Debug.startMethodTracing();//接下來做一些耗時操作Debug.stopMethodTracing();}接下來將文件導入到電腦,你們可以看下自己的SDK安裝目錄下的tools目錄下有一個traceview.bat文件,進入到這個目錄然后在dos中運行traceview C:\tracefile\dmtrace.trace,然后就能看到一個分析圖形了,最后按照官方文檔分析就行了
DDMS 工具
我今天就是用這個工具來進行數據采集,DDMS 的全稱是Dalvik Debug Monitor Service,是 Android 開發環境中的Dalvik虛擬機調試監控服務,可采集系統中某個正在運行的進程的函數調用信息;這個工具比較適合盲測,比如你也不知道具體哪個方法會出現耗時,那就通過它把APP的某一段使用過程進行方法追蹤分析
使用方法是在Android Studio里進行如下操作
或者直接在dos窗口中輸入monitor,接著就會彈出Android Device Monitor窗口:
點擊上圖中的按鈕你可能會彈出一個選擇框,如下
-
第一個:基于樣本的分析,通過在給定頻率上中斷VM并在那時收集調用堆棧來工作。 開銷與采樣頻率成正比
-
第二個:基于跟蹤的分析,通過跟蹤每個方法的進入和退出來工作。這捕獲了所有方法的執行,無論多小,因此具有高開銷
我這里選擇第二種
實例分析
接下來就使用這個工具再結合上面說的翻頁卡頓例子實際操作,看看如何分析卡頓原因
我們打開DDMS,點擊上方圖中的按鈕,然后做一次翻頁動作,接著再次點擊那個按鈕停止方法追蹤分析,這時DDMS會自動觸發Traceview工具來分析采集數據,并彈出可視化的面板,如下
我這里就是追蹤了一個翻頁動作的方法執行情況,這個面板分為三部分:
- A區域:羅列出追蹤過程中所采集到的線程信息,可以看到這里采集到了三個線程
- B區域:即Timeline Panel(時間線面板),標尺是時間線,下方是每個線程一個時間段內所涉及的方法調用信息,這些信息包括函數名、函數執行時間等,突出的顏色區域其實是由每個小立柱組成的,每個小立柱即代表一次方法調用,將鼠標放上去就會顯示相應的信息;你如果覺得太密集,可以滾動鼠標上的滾軸進行放大顯示
- C區域:即Profile Panel(分析面板),這個區域是Traceview的核心,非常詳細的展示了一段時間內該進程內的各個方法調用的情況,以及占用CPU時間,調用次數等信息,不過這里要注意這個時間是Java層方法執行時間,不包括Native層函數執行時間
Profile Panel
接下來重點就是分析這個Profile Panel了,那需要先了解這個面板上的名稱的意義,如下這幅圖:
該圖片頂部有多個英文名稱,含義如下
| Name | 追蹤期間所調用的方法 |
| Incl Cpu Time % | Cpu執行該方法及其子方法所花費時間占Cpu總執行時間的百分比 |
| Incl Cpu Time | Cpu執行該方法該方法及其子方法所花費的時間,以毫秒為單位 |
| Excl Cpu Time % | Cpu執行該方法所花費的時間占Cpu總時間的百分比,不包含內部調用其它方法時間 |
| Excl Cpu Time | Cpu執行該方法所花費的時間,不包含內部調用其它方法時間,以毫秒為單位 |
| Incl Real Time % | 該方法及其子方法從開始執行到結束所花費的實際時間占總時間的百分比 |
| Incl Real Time | 該方法及其子方法從開始執行到結束所花費的實際時間,以毫秒為單位 |
| Excl Real Time % | 該方法從開始執行到結束所花費的實際時間占總時間的百分比,不包含子方法 |
| Excl Real Time | 該方法從開始執行到結束所花費的實際時間,以毫秒為單位,不包含子方法 |
| Calls+Recur Calls/Total | 方法調用次數+遞歸次數 調用次數/總次數 【前半截是方法的數據,后半截是點擊方法后下方彈出的子方法的數據】 |
| Cpu Time/Call | Cpu執行時間和調用次數的百分比,表示每次調用所消耗的Cpu時間 |
| Real Time/Call | 方法執行實踐花費的時間和調用次數的百分比,表示該方法平均執行時間 |
我們可以點擊每個名稱進行排序,這里以Incl Cpu Time進行降序排列,點擊上圖中的第一行,如下圖:
可以看到占比最高的79.8%的方法是FlipRenderer類的onDrawFrame方法,并且CPU總的執行時間是817ms,這個方法就占用了652ms,從后面的Incl Real Time也表面該方法實際執行了1196ms,調用了24次;那我就繼續點擊這個方法看看,會跳到如下圖所示的結果
這個圖可以看到有Parents和Children兩欄,其中Parents下方表示調用該方法的父方法,Children下方表示該方法內部調用的子方法,接下來我們繼續點擊比例最高的方法進入看看,直到下方這個圖
最終可以看到是self這行的Incl Cpu Time比例最高,self代表自身方法中的語句執行情況,也就是說Cpu執行這個方法自身語句所花費的時間最多;同時可以看下Incl Real Time的值,除去執行自己語句的484.144ms的耗時,內部還調用了一個GLUtils.texSubImage2D方法耗時507.571ms;這樣翻頁慢的原因就是這個createTexture方法了
其實從后面的Calls+Recur Calls/Total 可以看出來createTexture方法被調用了48次,Incl Real Time值表明48次調用花費時間是1032.437ms,平均一次調用要1032.437/4821.509 = 21.509ms,跟Real Time/Call值是一樣的,這也說明這種UI卡頓是屬于單次執行不耗時,但是調用次數多了就耗時的情況
通過對比發現,這一個createTexture方法在其它設備上執行一次只需要5ms左右,但是在這個設備上執行一次時間就翻了5倍;一看手機使用的是一款聯發科的低配版cpu,不過最后還是自己優化了下這個方法,降低執行所花費的時間,基本算解決了這個問題;大家也可以使用這個方法去分析下自己app里的UI卡頓原因
總結
以上是生活随笔為你收集整理的使用TraceView+实际案列实战性能分析 找出android app UI卡顿原因的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java网络编程(9)NIO - 群聊系
- 下一篇: sqlserver安装显示句柄无效_句柄