回顾市面上大多数的开源监控方案,大多采用ANR
这种机制下的做法去实现卡顿的监控,进而进行堆栈信息的追溯采集等。ANR
这种方案最大的优点在于采集数据的准确率很高,基本可以说一旦发现主线程被block
住了,那是一抓一个准的。但是同样也有着自己的缺陷,即ping
的周期阈值的问题。
目前多数的做法是在子线程中周期性的ping
主线程判断主线程是否被堵塞。如果不能在阈值内ping
成功,说明主线程已经发生了卡顿
因此,此方案的问题在于这个ping
周期应该是多长。本身在实现一套性能监控体系时,我们必须去衡量导入这个工具会带来怎样的损耗,因此这个周期不能太短。同样的,太长的周期也必然会漏掉可能发生的卡顿现象,而且这个概率不低。
最近出现了一个称作平滑度
的概念,通过应用使用前后的平滑对比来判断是否产生了卡顿问题。目前笔者没有看到相关的处置代码,但是并不妨碍笔者对这种方案的猜测。通过所谓的平滑度对比
应该是通过FPS
查看应用运行过程中的帧数变化。我们都知道通常情况下,屏幕会保持60帧/秒
的刷新频率,如果在某一帧发生了大量计算导致跳帧
,也可以称作掉帧
现象,具体表现就是我们感受到的卡顿。
这种卡顿采用ANR
其实是很难检测到的,这是视觉上的卡顿而非Not Response
。因此除了CADisplayLink
和人工测试之外,还是相当难的去捕获到这种卡顿。
所以,一种改进的方案是放弃现有的纯ANR
方式的卡顿监控方案,结合CADisplayLink
来实现另一种方式的监控。大致为主线程监听屏幕刷新信号,子线程循环获取FPS
,并判断是否发生下滑现象。如果发生下滑,此时再尝试去ping
主线程判断是否被block
住。相比起纯ANR
方案,这种方式的ping
目的性更强,但是由于监控FPS
的变化也是有时间的消耗的。这意味着短时的主线程block
可能在ping
出去没多久时就已经恢复,实际发生的卡顿却没有被监控到,也算是这种方案的缺陷了。
上面的方案属于个人猜测的方案,具体效果如何还需要去实践得真知。对于卡顿监控来说,有两个相当重要的指标。准确率
与捕获率
,这两者在一定意义上是互相矛盾的,我们所做的工作无非是尽量在两者之间权衡比较,得出当下最有利的方案。不过如果非要二选一的话,个人还是选择准确率
。毕竟只要有足够的时间和样本采集,捕获率
即便低了一些也总归有机会采集的到。