matrix

Matrix Tencent

一:TraceCanary

插桩:通过插桩,在除了get/set、默认或匿名构造函数等简单函数外的所有方法,入口/出口插入MethodBeat.i()/MethodBeat.o()。

image-20210729175300794

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//AppMethodBeat.java
private static void mergeData(int methodId, int index, boolean isIn) {
if (methodId == AppMethodBeat.METHOD_ID_DISPATCH) {
sCurrentDiffTime = SystemClock.uptimeMillis() - sDiffTime;
}
long trueId = 0L;
if (isIn) {
trueId |= 1L << 63;
}
trueId |= (long) methodId << 43;
trueId |= sCurrentDiffTime & 0x7FFFFFFFFFFL;
sBuffer[index] = trueId;
checkPileup(index);
sLastIndex = index;
}

用一个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 前的所有数据(即两帧之间的所有函数执行信息)进行分析上报。

二:APK Tracker

apk体积检测

三:Hook

黑科技,hook 系统以达到32位设备中获得更大的虚拟内存

四:IOCanary

Author

white crow

Posted on

2021-05-26

Updated on

2024-03-25

Licensed under