matrix
Matrix Tencent
一:TraceCanary
插桩:通过插桩,在除了get/set、默认或匿名构造函数等简单函数外的所有方法,入口/出口插入MethodBeat.i()/MethodBeat.o()。
1 | //AppMethodBeat.java |
用一个64位的long型来存储方法的:方法开始/方法结束(最高位63位)、方法id(递增,43到62位)、当前与MethodBeat模块初始化时差(0到42位)
during计算:考虑到每个方法执行前后都获取系统时间(System.nanoTime)会对性能影响比较大,而实际上,单个函数执行耗时小于 5ms 的情况,对卡顿来说不是主要原因,可以忽略不计,如果是多次调用的情况,则在它的父级方法中可以反映出来,所以为了减少对性能的影响,通过另一条更新时间的线程每 5ms 去更新一个时间变量,而每个方法执行前后只读取该变量来减少性能损耗。(sTimerUpdateThread)
example(初始化时差未体现):
后面生成调用栈树 输出结果的可以参考(微信团队自研的APM利器,Matrix性能监控日志探索 (qq.com) 的6.2 生成调用栈树)
上述项作为基础 (函数耗时= 每个函数调用上报 + 每个函数统计耗时)
EvilMethodTracer:
注册主线程handler 的Looper.looper,printer消息回调,在每一个dispatchBegin与dispatchEnd的差距超过700ms时触发上报
ANRTracer:
注册主线程handler 的Looper.looper,printer消息回调,在每一个dispatchBegin时postDelay一个5s后的ANR上报消息,并在dispatchEnd时候removeCallback这个消息。
如果消息五秒后还没有被移除掉,那就说明发生了ANR,会主动取出当前记录的 buffer 数据进行独立分析并产生上报。如果一切正常(该message5s内执行完成),那么自然会取消掉并继续用这种方式监听下一个消息。
FrameTracer:
向 Choreographer 注册监听,在每一帧 doframe 回调时判断距离上一帧的时间差是否超出阈值(卡顿),如果超出阈值,则获取数组 index 前的所有数据(即两帧之间的所有函数执行信息)进行分析上报。