前言:
之前根據(jù) Android Studio Profiler 查看卡頓問題 已經解決了部分已知問題「即:有明確場景,進而暴露出來的問題」鳄虱;
不足的點是:問題暴露之前尋找卡頓的點藐守,抓取的 hprof 文件操作復雜锯梁,尋找問題時效率較低苦囱,具體每個函數(shù)的耗時不可統(tǒng)計 ;
所以需要尋找比較成熟的卡頓工具麻裁,幫助我們定位問題.
工具對比:
BlockCanary: 依賴主線程 Looper,監(jiān)控每次 dispatchMessage 的執(zhí)行耗時源祈;
ArgusAPM / LogMonitor: 依賴 Choreographer 模塊煎源,監(jiān)控相鄰兩次 Vsync 事件通知的時間差;
以上方式的問題:
無法獲取到各個函數(shù)的執(zhí)行耗時香缺,對于稍微復雜一點的堆棧手销,很難找出可能耗時的函數(shù),也就很難找到卡頓的原因图张;
通過其他線程循環(huán)獲取主線程的堆棧锋拖,如果稍微處理不及時,很容易導致獲取的堆棧有所偏移祸轮,不夠準確姑隅,加上沒有耗時信息,卡頓也就不好定位倔撞;
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 為調用堆棧鄙陡;
stackKey 則能唯一標識調用堆棧;
本文只針對 stack 如何解析躏啰,以方便開發(fā)人員定位問題趁矾;
matrix-stack 詳解:
stack每行格式:stack層級,方法id给僵,方法執(zhí)行次數(shù)毫捣,方法執(zhí)行總耗時详拙;
methodmap是插樁函數(shù)表,每行格式:方法id蔓同,方法accessType饶辙,類名,方法名斑粱,方法描述弃揽;
使用:
- 將 matrix 生成的 methodMapping.txt 保存下來「每一次 build,會生成唯一對應 methodMapping.txt」;
- 根據(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
注:上面的文件不能含有多余空格 按照格式去寫矿微;
- matrix-trace-processor download 項目到本地,執(zhí)行python腳本,生成
python3 main.py workflow_traces stack.log > stack_processor.txt methodMapping.txt
此時 stack_processor.txt 已經是 DTrace 格式的堆棧文件尚揣,可以利用 FlameGraph 這個庫生成火焰圖涌矢,方便開發(fā)者生成調用棧;
注:這個庫同樣有腳本可以根據(jù) stack 生成 log 文件快骗,但是我認為使用不方便娜庇,可以看這里matrix-trace-processor 解析
- FlameGraph項目到本地,執(zhí)行腳本
stackcollapse.pl stack_processor.txt > stack.folded
flamegraph.pl stack.folded > stack.svg
最終將 stack 的 string 轉化為可直接在瀏覽器打開的 svg 格式的調用棧
注:電腦若為 windows 需要查看 perl 是否安裝滨巴,上面的腳本文件是用 perl 寫的
檢查 perl 是否已安裝:
perl -v
最終生成的文件如下:
經過上面的步驟思灌,自己開發(fā)用來檢測已經可以了,but 我「Andorid」做了一個 python 項目「因為后端沒人鳥我」恭取,把 matrix 的日志上報到服務端泰偿,可根據(jù) 方法耗時cost 和 stackKey 去查看 svg 文件,方便組內人員開發(fā)蜈垮;
需要 python + 數(shù)據(jù)庫耗跛,就能做這個事情,有興趣可以整一下攒发;