学习BlockCanary的实现

What is BlockCanary

Android平台的开源主线程性能检测开源库。

作者博客 http://blog.zhaiyifan.cn/2016/01/16/BlockCanaryTransparentPerformanceMonitor/?utm_source=tuicool&utm_medium=referral

Github : https://github.com/markzhai/AndroidPerformanceMonitor

Android如何获取主线程堆栈信息

Thread.getStackTrace()方法。

如何在其他线程获取主线程引用 : Looper.getMainLooper().getThread();

如何Cpu使用情况

获取Cpu总数据,来自CpuSampler的doSample方法


从 /proc/stat 中读取Cpu信息,可参考 http://www.blogjava.net/fjzag/articles/317773.html

执行parse方法,解析相关数据,可以获取到 total, idle, user 等cpu使用情况


获取当前进程的cpu数据,同是doSample方法


进程相关的cpu占用情况,数据取自 "/proc/" + mPid + "/stat" 文件

同样通过parse方法进行解析


如何跟踪主线程的时间执行情况

在主线程msg.target.dispatchMessage前后有被打印,两次打印之间的时间差就是这个dispatch 的message所被执行的时间。


如何检测到dispatchMessage前后的log被执行

Looper有一个setMessageLogging可以设置自己的Printer


BlockCanary实现的自定义Printer 为 LooperMonitor,当dispatchMessage前后的log执行的是LooperMonitor的println 

从println的代码中,可以知道

dispatchMessage之前的log被打印时,执行的红色部分,即:

  1. 记录当前的时间戳
  2. startDump

dispatchMessage之后的log被打印时,执行的绿色部分,即:

  1. 计算此次消费事件是否block
  2. 如果block,执行notifyBlockEvent
  3. stopDump

判断是否block


是否block,就是判断的开始log 与 结束log的时间差是否大于设定的阀值

当block时 , 执行notifyBlockEvent


发生了block时,执行mBlockListener的onBlockEvent方法。

HandlerThreadFactory.getWriteLogThreadHandler实际上是返回的新建子线程的hander,也就是说,mBlockListener.onBlockEvent是在子线程进行的一个回调。


mBlockListener.onBlockEvent具体做了什么?我们找到设置的地方


构造器中设置了blockListener,我们找到创建LooperMonitor的地方


onBlockEvent : 我们得知,只有发生block时,才进行LogWriter的保存

  1. 获取线程堆栈信息
  2. LogWriter 保存blockInfo
  3. 通知所有interceptor onBlock.

Printer 的 println方法中如何通过startDump开始收集快照 ,stopDump停止收集快照

LooperMonitor的startDump方法


我们发现stackSampler  和 cpuSampler是 BlockCanaryInternals的成员变量,并且在构造器中进行了初始化


stackSampler 和 cpuSampler的 start方法


主要就是使用一个handler postDelay了一个Runnable对象。关于这个handler对象,我们再看下HandlerThreadFactory的代码


通过上面的代码,我们得知,实际这个handler是一个子线程的handler,也就是开启的一个子线程在xx毫秒后执行Runnable对象的run方法,这个Runnable对象的run方法又做了什么呢?


通过上面的代码可知:

  1. 执行了doSample(),CpuSampler的doSample采集 cpu , StackSampler的doSample采集 堆栈信息
  2. 判断是否设置采集为true.
  3. 循环采样:如果设置采集为true,采样后,继续postDelay一个Runnable对象用于继续采集下一周期。

如何停止收集快照


调用AbstractSampler的stop方法,即设置一个标志位,在循环采样中进行了判断,当标志位为false时,循环采样终止。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值