matrix
Matrix Tencent
一:TraceCanary
插桩:通过插桩,在除了get/set、默认或匿名构造函数等简单函数外的所有方法,入口/出口插入MethodBeat.i()/MethodBeat.o()。
1 | //AppMethodBeat.java |
用一个64位的long型来存储方法的:方法开始/方法结束(最高位63位)、方法id(递增,43到62位)、当前与MethodBeat模块初始化时差(0到42位)
插桩:通过插桩,在除了get/set、默认或匿名构造函数等简单函数外的所有方法,入口/出口插入MethodBeat.i()/MethodBeat.o()。
1 | //AppMethodBeat.java |
用一个64位的long型来存储方法的:方法开始/方法结束(最高位63位)、方法id(递增,43到62位)、当前与MethodBeat模块初始化时差(0到42位)
*Retrofit通过 反射构建一个 接口的 实现类(动态代理本质就是反射),其中每个重写方法被调用时,都会回调到InvocationHandler.invoke中,invoke回调时(只要是不是object类中的方法)都会通过 获取到的方法的注解、方法的名称、方法的返回值、方法参数的注解、方法参数类型等等所需信息, 解析成一个ServiceMethod对象(放入缓存池),ServiceMethod根据获取到的方法信息,构建OkHttp请求,并将结果通过converter转换后回调给最初传入的Callback
链接:https://juejin.cn/post/6887896333685161992
简述:
通过对外提供的OkHttpClient和Request的builder实现基础信息和必要信息的配置,直到封装构建成了RealCall对象(RealCall implement Call)并新建CallBack实例传入realCall.equeue(callback),才真正完成了请求实体的实例化。
之后realCall.enqueue(call)方法的调用才是实际上开始进行请求:先判断是否call已经执行过了(executed = AtomicBoolean()),若未执行则继续
之后由Dispatcher调用enqueue进行判断当前正在执行的请求数及当前网络请求的主机数是否超过了最大值。要是超过了最大值,就将请求放到等待队列中,要是没超过,就放到正在执行的队列中,然后调用线程池(默认单例初始化了一个缓存线程池(即无核心线程、无限线程池数量、SynchronousQueue
线程栈中的局部变量表引用的所有变量,即运行线程中引用到的所有变量,包括线程中方法参数和局部变量
存活的线程对象
native 的 jni引用
class 对象 (classLoader 不会卸载class)
引用类型的静态变量
// 1跟2其实说的是一个东西
Reference queues, to which registered reference objects are appended by the garbage collector after the appropriate reachability changes are detected.
在检测到适当的可达性改变后,垃圾收集器将注册的引用对象(WeakReference)追加到引用队列(ReferenceQueue)。
核心思路是:
leakCanary做法是ondestory后手动出发GC,GC过后对象WeakReference一直不被加入 ReferenceQueue,它可能存在内存泄漏。
利用 双参初始化的弱引用 WeakReference(T referent, ReferenceQueue<? super T> q) 在object对象变成弱可达的时候(可视为已被回收/(其他非强引用也一样)),会将该WeakReference对象入队q中 的特性(也就是queque中最后会存在已经被回收了的weakreference对象),通过在Activity和Fragment的onDestroy()中,将该Activity或Fragment实例的弱引用初始化(双参object,queue)后放入map中(key随机固定uuid),GC后 把map中的 queue包含的对象 移除,map中剩余的即为可能泄露的对象