如何來快速定位啟動時間中的異常方法(Android版)
目前工具已開源,項目地址:alexknight/TraceAnalysis ,歡迎star
1.啟動時間測試常用方案介紹
如何精確測試啟動時間,其實這個問題可大可小,主要需要看團隊對啟動時間的測試精度要求,當啟動時間測試誤差需要精確到小几十毫秒時,很多問題都會暴露,因為其實目前很難有一種方式去評估數據的有效性。當前設備狀態,CPU溫度,內存,系統GC,研發人員的代碼以及線程模式等,都有可能導致啟動時間波動增大。目前已知的啟動時間測試方案有幾種,可以例舉一下:
- 插樁法:通過在整個啟動的生命周期打日誌,然後通過解析日誌來得到本次啟動時間
- 錄屏分幀:包括高速攝像頭或者其他客戶端錄屏/截圖,通過錄製啟動時間的整個過程,通過做分幀處理,來得到起始結束位置
但其實這些方法都有各自的問題,插樁引入的測試誤差本身很小,但因為系統誤差的關係,會導致本身波動會很大,而錄屏分幀,雖然可以用於競品分析,但測試誤差會比較大,目前工業級的攝像頭,也只能到8ms/幀率,一般高速攝像頭的也會引入33ms的系統誤差,此外,如果在android端錄屏,可能會導致啟動時間波動更加增大,因此如果單純從測試方法上來改善啟動時間測試,效果肯定不會好。因為我們需要明白,系統隨機誤差的引入,所以啟動時間的測試數據是一個概率問題,而不是一個可以100%一定出現在某個區域的問題(有時間寫一篇統計學跟誤差分析的文章)。
其實自然而然這就引申出兩個問題:
- 問題定位方法的改進
- 誤差需要用科學的方法去做估算
當然這篇文章只講第一個問題,也就是怎麼去定位啟動時間問題,下面進入正題。
2.啟動時間問題定位方案
在這裡要推薦的是Traceview。Traceview的介紹可以看這篇文章:正確使用 Android 性能分析工具--TraceView · TesterHome
因為系統隨機誤差比較大,因此單獨看某一個生命周期中的耗時,並不能幫助定位問題,而Traceview可以幫我們查看到每一個線程的調用棧以及方法的CPU時間或者堆棧累加時間。往往可以通過Traceview來做問題定位,但目前有一些限制:
- 操作不超過5s
- 在IDE上查看才比較方便
- 大部分方法都混淆了,很難有效定位到對應的方法
其實這些問題都不是問題
- Traceview可以通過android.os.Debug.startMethodTracing();和android.os.Debug.stopMethodTracing();來打點,生成這段啟動周期的Trace數據
- google提供了一個半成品dmtracedump,可以解析Traceview文件,當然也只是半成品,但我們可以自己解析,但是是有辦法突破IDE限制的
- 混淆問題其實不算問題,一般都有自己的mapping文件去解混淆
3.方案應用
我們在版本迭代中,每一個小版本演進時,其實變動的方法並不會太多,那麼,Traceview既然能看到進程,方法佔用的CPU時間片,那我可以把所有的方法耗時做統計並做耗時排序,過濾掉系統線程以及不需要關注的線程,著重對比新增的方法以及改動的方法,然後我們逐一去過濾top異常的方法就行了。
實際應用上可以發現,用反混淆後的包去做對比測試,是可以很明顯看到一些異常的耗時方法的。
4.思路拓展
這塊其實還可以繼續拓展一下,但我這塊沒有實踐,可以把我的想法拋出來給大家。
- 反混淆操作
- 通過對比兩個版本的Traceview方法,可以過濾出top方法
- 拿到兩個revision間的svnlog,過濾出改動的方法
- 對比svnlog跟top異常方法,自動將可疑方法郵件發給研發,實現監控問題到定位問題的閉環。
5.開源一個工具
代碼是一年半前寫的,原來也只是邊探索邊驗證效果,後面沒有做重構,所以代碼質量並不高。最近僅僅只是把功能抽了出來,如果能夠幫到你,隨手star讓我更有動力輸出一些有用的東西。
目前工具實現的功能包括
- 支持反混淆
- 支持獲取Traceview文件的解析結果,json對象返回
- 提供默認模板,支持Traceview兩兩對比,生成csv的結果文件
6.效果展示
在這裡,展示一下traceview文件解析後獲取到的json數據內容。其中包括了
- call_times每個方法的調用次數
- costs:總耗時時長
- exclusive:每個方法的cpu時間片以及調用棧
- inclusive:包含了每個方法及孩子方法的時間累加
- method_thread:包含了涉及到該trace涉及到的所有線程
- sorted_dic:對所有耗時方法做了排序以tuple方式存儲在list中
- threads_pid:各個線程對應的pid
推薦閱讀:
TAG:測試開發 | Android開發 | android自動化測試 |