微信iOS卡顿监控系统

作者: Crazy2015 | 来源:发表于2019-05-29 20:28 被阅读45次
界面卡顿是由哪些原因导致的?
  • 死锁:主线程拿到锁 A,需要获得锁 B,而同时某个子线程拿了锁 B,需要锁 A,这样相互等待就死锁了。

  • 抢锁:主线程需要访问 DB,而此时某个子线程往 DB 插入大量数据。通常抢锁的体验是偶尔卡一阵子,过会就恢复了。

  • 主线程大量 IO:主线程为了方便直接写入大量数据,会导致界面卡顿。

  • 主线程大量计算:算法不合理,导致主线程某个函数占用大量 CPU。

  • 大量的 UI 绘制:复杂的 UI、图文混排等,带来大量的 UI 绘制。

针对这些原因,我们可以怎么定位问题呢?
  • 死锁一般会伴随 crash,可以通过 crash report 来分析。

  • 抢锁不好办,将锁等待时间打出来用处不大,我们还需要知道是谁占了锁。

  • 大量 IO 可以在函数开始结束打点,将占用时间打到日志中。

  • 大量计算同理可以将耗时打到日志中。

  • 大量 UI 绘制一般是必现,还好办;如果是偶现的话,想加日志点都没地方,因为是慢在系统函数里面。

如果可以将当时的线程堆栈捕捉下来,那么上述难题都迎刃而解。主线程在什么函数哪一行卡住,在等什么锁,而这个锁又是被哪个子线程的哪个函数占用,有了堆栈,我们都可以知道。自然也能知道是慢在UI绘制,还是慢在我们的代码。

所以,思路就是起一个子线程,监控主线程的活动情况,如果发现有卡顿,就将堆栈 dump 下来

流程图描述如下:
image.png

细节
原理一旦讲出来,好像也不复杂。魔鬼都是隐藏在细节中,效果好不好,完全由实现细节决定。具体到卡顿检测,有几个问题需要仔细处理:

  • 怎么知道主线程发生了卡顿?

  • 子线程以什么样的策略和频率来检测主线程?这个是要发布到现网的,如果处理不好,带来明显的性能损耗(尤其是电量),就不能接受了。

  • 堆栈上报了上来怎么分类?直接用 crash report 的分类不适合。

  • 卡顿 dump 下来的堆栈会有多频繁?数据量会有多大?

  • 全量上报还是抽样上报?怎么在问题跟进与节省流量直接平衡?

1. 判断标准

怎么判断主线程是不是发生了卡顿?一般来说,用户感受得到的卡顿大概有三个特征:

  • FPS 降低

  • CPU 占用率很高

  • 主线程 Runloop 执行了很久

看起来 FPS 能够兼容后面两个特征,但是在实际操作过程中发现 FPS 不好衡量,抖动比较大。而对于抢锁或大量 IO 的情况,光有 CPU 是不行的。所以我们实际上用到的是下面两个准则:

  • CPU 占用超过了100%

  • 主线程 Runloop 执行了超过2秒

2. 检测策略

为了降低检测带来的性能损耗,我们仔细设计了检测线程的策略:

  • 内存 dump:每1秒检查一次,如果检查到主线程卡顿,就将所有线程的函数调用堆栈 dump 到内存中。

  • 文件 dump:如果内存 dump 的堆栈跟上次捕捉到的不一样,则 dump 到文件中;否则按照斐波那契数列将检查时间递增(1,1,2,3,5,8…)直到没有遇到卡顿或卡顿堆栈不一样。这样能够避免同一个卡顿写入多个文件的情况,也能避免检测线程围着同一个卡顿空转的情况。

3. 分类方法

直接用 crash report 的分类方法是不行的,这个很好理解:最终卡在 lock 函数的卡顿,外面可能是很多不同的业务,例如可能是读取消息,可能是读取联系人,等等。卡顿监控需要仔细定义自己的分类规则。可以是从调用堆栈的最外层开始归类,或者是取中间一部分归类,或者是取最里面一部分归类。各有优缺点:

  • 最外层归类:能够将同一入口的卡顿归类起来。缺点是层数不好定,可能外面十来层都是系统调用,也有可能第一层就是微信的函数了。

  • 中间层归类:能够根据事先划分好的“特征值”来归类。缺点是“特征值”不好定,如果要做到自动学习生成的话,对后台分析系统要求太高了。

  • 最内层归类:能够将同一原因的卡顿归类起来。缺点是同一分类可能包含不同的业务。

转载地址:
https://mp.weixin.qq.com/s?__biz=MzAwNDY1ODY2OQ%3D%3D&idx=1&mid=207890859&scene=23&sn=e98dd604cdb854e7a5808d2072c29162&srcid=0921FzoCw9j1W7n4uFYKuarC#rd

相关文章

  • iOS通过runloop监控卡顿

    质量监控-卡顿检测iOS实时卡顿监控基于Runloop简单监测iOS卡顿的demo微信iOS卡顿监控系统iOS-R...

  • 卡顿检测资料

    微信iOS卡顿监控系统 卡顿方案思考 卡顿检测 移动端监控体系之技术原理 iOS性能检测

  • 性能

    微信iOS卡顿监控系统 wojteklu/Watchdog https://tech.meituan.com//p...

  • 简单监测iOS卡顿的demo

    前言 本文的demo代码也会更新到github上。 做这个demo思路来源于微信team的:微信iOS卡顿监控系统...

  • 微信iOS卡顿监控系统

    界面卡顿是由哪些原因导致的? 死锁:主线程拿到锁 A,需要获得锁 B,而同时某个子线程拿了锁 B,需要锁 A,这样...

  • Matrix-iOS 卡顿、内存监控 (一)

    Matrix-iOS 卡顿监控Matrix-iOS 内存监控 一、卡顿检测 Matrix-iOS 在addMoni...

  • iOS 性能优化-读书笔记

    1.微信读书 iOS 性能优化总结 2.iOS实时卡顿监控 3.获取iOS任意线程调用堆栈(五)完整实现:BSBa...

  • iOS 卡顿监控

    界面卡顿是哪些问题导致的? 死锁:主线程拿到锁A,需要获得锁B,而同时某个子线程拿了锁B,需要锁A,这样互相等待就...

  • ios卡顿监控

    一般认为卡顿主要指主线程卡顿。针对 UI 卡顿或者说主线程卡顿可以有多种监控方案: 1、利用 CADisplayL...

  • signal causes debugger to stop a

    问题:最近在做iOS UI卡顿监控,为了具体定位到卡顿的函数栈,使用到了pthread_kill,但是debug状...

网友评论

    本文标题:微信iOS卡顿监控系统

    本文链接:https://www.haomeiwen.com/subject/lcyutctx.html