Matrix-TraceCanary 實際使用

前言:
之前根據(jù) Android Studio Profiler 查看卡頓問題 已經(jīng)解決了部分已知問題「即:有明確場景,進而暴露出來的問題」;
不足的點是:問題暴露之前尋找卡頓的點,抓取的 hprof 文件操作復(fù)雜,尋找問題時效率較低,具體每個函數(shù)的耗時不可統(tǒng)計 ;
所以需要尋找比較成熟的卡頓工具,幫助我們定位問題.

工具對比:
BlockCanary: 依賴主線程 Looper,監(jiān)控每次 dispatchMessage 的執(zhí)行耗時;
ArgusAPM / LogMonitor: 依賴 Choreographer 模塊,監(jiān)控相鄰兩次 Vsync 事件通知的時間差;

以上方式的問題
無法獲取到各個函數(shù)的執(zhí)行耗時,對于稍微復(fù)雜一點的堆棧,很難找出可能耗時的函數(shù),也就很難找到卡頓的原因;
通過其他線程循環(huán)獲取主線程的堆棧,如果稍微處理不及時,很容易導(dǎo)致獲取的堆棧有所偏移,不夠準確,加上沒有耗時信息,卡頓也就不好定位;

Matrix-TraceCanary 優(yōu)勢:
在編譯期間修改字節(jié)碼;
準確定位卡頓函數(shù),并顯示堆棧/執(zhí)行次數(shù)/耗時;

使用問題:
TraceCanary 暴露 3 種類型問題:
??Trace_StartUp「啟動」
??Trace_EvilMethod「慢函數(shù)」
??Trace_FPS「幀率」
其中 Trace_EvilMethod 模塊中所給數(shù)據(jù)格式如下:

{
    "machine":"MIDDLE",
    "cpu_app":0.05800059283652189,
    "mem":6124523520,
    "mem_free":3195336,
    "detail":"NORMAL",
    "cost":230,
    "usage":"87.34%",
    "scene":"com.*.android.pokekara.*.main.*Activity",
    "stack":"0,1048574,1,230\n1,30791,1,226\n2,30756,1,226\n3,30754,1,226\n4,22474,1,226\n5,22603,1,226\n6,145827,1,204\n7,145985,1,199\n8,139523,1,128\n9,180666,1,128\n10,180669,1,128\n11,29838,1,11\n12,29855,1,11\n8,139524,1,66\n9,21060,1,66\n10,21116,1,49\n11,21207,1,17\n12,28079,1,17\n13,28035,1,17\n14,29464,1,17\n15,28388,1,17\n16,28293,1,17\n17,28296,1,17\n18,60995,1,12\n11,21145,1,11\n12,21152,1,11\n10,21063,1,12\n11,142855,1,12\n12,142531,1,12\n13,142851,1,12\n",
    "stackKey":"145985|",
    "tag":"Trace_EvilMethod",
    "process":"com.*.android.*",
    "time":1650008010859,
    "type":0,
    "build_id":"1650007387169",
    "device_id":"6862573909639700608",
    "upload_time":1650008010860
}

stack 為調(diào)用堆棧;
stackKey 則能唯一標識調(diào)用堆棧;
本文只針對 stack 如何解析,以方便開發(fā)人員定位問題;

matrix-stack 詳解:
stack每行格式:stack層級,方法id,方法執(zhí)行次數(shù),方法執(zhí)行總耗時;
methodmap是插樁函數(shù)表,每行格式:方法id,方法accessType,類名,方法名,方法描述;

使用:

  1. 將 matrix 生成的 methodMapping.txt 保存下來「每一次 build,會生成唯一對應(yīng) methodMapping.txt」;
  2. 根據(jù) stack 生成 stack.log 文件,這塊是我自己用 python 寫的,最后生成 stack.log 文件如下:
0,1048574,1,300\n
1,29689,1,283\n
2,4534,1,283\n
...
11,83065,1,278\n
15,78775,1,278\n
...
24,3174,1,123\n
20,81443,1,67\n

注:上面的文件不能含有多余空格 按照格式去寫;

  1. matrix-trace-processor download 項目到本地,執(zhí)行python腳本,生成
python3 main.py workflow_traces stack.log > stack_processor.txt methodMapping.txt

此時 stack_processor.txt 已經(jīng)是 DTrace 格式的堆棧文件,可以利用 FlameGraph 這個庫生成火焰圖,方便開發(fā)者生成調(diào)用棧;

注:這個庫同樣有腳本可以根據(jù) stack 生成 log 文件,但是我認為使用不方便,可以看這里matrix-trace-processor 解析

  1. FlameGraph項目到本地,執(zhí)行腳本
 stackcollapse.pl stack_processor.txt > stack.folded
 flamegraph.pl stack.folded > stack.svg

最終將 stack 的 string 轉(zhuǎn)化為可直接在瀏覽器打開的 svg 格式的調(diào)用棧
注:電腦若為 windows 需要查看 perl 是否安裝,上面的腳本文件是用 perl 寫的

檢查 perl 是否已安裝:

perl -v

最終生成的文件如下:


stack.svg

經(jīng)過上面的步驟,自己開發(fā)用來檢測已經(jīng)可以了,but 我「Andorid」做了一個 python 項目「因為后端沒人鳥我」,把 matrix 的日志上報到服務(wù)端,可根據(jù) 方法耗時cost 和 stackKey 去查看 svg 文件,方便組內(nèi)人員開發(fā);
需要 python + 數(shù)據(jù)庫,就能做這個事情,有興趣可以整一下;

感謝
matrix-trace-processor
FlameGraph

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容