Matrix-TraceCanary 实际使用

前言:
之前根据 Android Studio Profiler 查看卡顿问题 已经解决了部分已知问题「即:有明确场景,进而暴露出来的问题」;
不足的点是:问题暴露之前寻找卡顿的点,抓取的 hprof 文件操作复杂,寻找问题时效率较低,具体每个函数的耗时不可统计 ;
所以需要寻找比较成熟的卡顿工具,帮助我们定位问题.

工具对比:
BlockCanary: 依赖主线程 Looper,监控每次 dispatchMessage 的执行耗时;
ArgusAPM / LogMonitor: 依赖 Choreographer 模块,监控相邻两次 Vsync 事件通知的时间差;

以上方式的问题
无法获取到各个函数的执行耗时,对于稍微复杂一点的堆栈,很难找出可能耗时的函数,也就很难找到卡顿的原因;
通过其他线程循环获取主线程的堆栈,如果稍微处理不及时,很容易导致获取的堆栈有所偏移,不够准确,加上没有耗时信息,卡顿也就不好定位;

Matrix-TraceCanary 优势:
在编译期间修改字节码;
准确定位卡顿函数,并显示堆栈/执行次数/耗时;

使用问题:
TraceCanary 暴露 3 种类型问题:
  Trace_StartUp「启动」
  Trace_EvilMethod「慢函数」
  Trace_FPS「帧率」
其中 Trace_EvilMethod 模块中所给数据格式如下:

{
    "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 如何解析,以方便开发人员定位问题;

matrix-stack 详解:
stack每行格式:stack层级,方法id,方法执行次数,方法执行总耗时;
methodmap是插桩函数表,每行格式:方法id,方法accessType,类名,方法名,方法描述;

使用:

  1. 将 matrix 生成的 methodMapping.txt 保存下来「每一次 build,会生成唯一对应 methodMapping.txt」;
  2. 根据 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 项目到本地,执行python脚本,生成
python3 main.py workflow_traces stack.log > stack_processor.txt methodMapping.txt

此时 stack_processor.txt 已经是 DTrace 格式的堆栈文件,可以利用 FlameGraph 这个库生成火焰图,方便开发者生成调用栈;

注:这个库同样有脚本可以根据 stack 生成 log 文件,但是我认为使用不方便,可以看这里matrix-trace-processor 解析

  1. FlameGraph项目到本地,执行脚本
 stackcollapse.pl stack_processor.txt > stack.folded
 flamegraph.pl stack.folded > stack.svg

最终将 stack 的 string 转化为可直接在浏览器打开的 svg 格式的调用栈
注:电脑若为 windows 需要查看 perl 是否安装,上面的脚本文件是用 perl 写的

检查 perl 是否已安装:

perl -v

最终生成的文件如下:


stack.svg

经过上面的步骤,自己开发用来检测已经可以了,but 我「Andorid」做了一个 python 项目「因为后端没人鸟我」,把 matrix 的日志上报到服务端,可根据 方法耗时cost 和 stackKey 去查看 svg 文件,方便组内人员开发;
需要 python + 数据库,就能做这个事情,有兴趣可以整一下;

感谢
matrix-trace-processor
FlameGraph

你可能感兴趣的:(Matrix-TraceCanary 实际使用)