Skip to main content

Matrix

Matrix-iOS 卡顿监控

微信 iOS 卡顿监控系统

WCCrashBlockMonitorPlugin:基于 KSCrash 的卡顿堆栈捕获,同时兼备崩溃捕获。还可以监控 CPU 高占用、电量高占用。

WCMemoryStatPlugin:爆内存监控。注意开启之后对性能损耗较大,建议按需开启。

主线程发生卡顿时,还去获取线程快照,不会造成更卡吗?

线程快照是直接调用操作系统内核的用户接口,获取系统提供的信息,本身不涉及额外的复杂计算,占用 CPU 非常少。真正耗时的,是获取堆栈后需要写入到文件。

因此,为了降低性能损耗,我们为检测线程增加了退火算法:每次子线程检查到主线程卡顿,会先获得主线程的堆栈并保存到内存中,并与上次卡顿获得的主线程堆栈进行比对:

  • 如果堆栈不同,则将其并写入文件中;
  • 如果相同则会跳过,并按照斐波那契数列将检查时间递增,直到没有遇到卡顿或者主线程卡顿堆栈不一样。

这样,可以避免同一个卡顿多次写入文件的情况;避免检测线程遇到主线程卡死的情况下,不断写线程快照文件。

特别地,在键盘 Extension 中的实现更加保守,一次卡顿仅记录一次,然后等待信号量,不会重复写文件。

获取到的线程快照就是造成卡顿的堆栈吗?

子线程检测到主线程卡顿时,会获得当前的线程快照写入文件。但是这个当前的主线程堆栈不一定是最耗时的堆栈,不一定是导致主线程超时的原因。

子线程在超时后获取线程快照,此时主线程的任务是“画小气泡”,但其实“画大气泡”才是耗时操作,是导致主线程超时的主要原因。为此,Matrix 通过耗时堆栈提取来解决这个问题。

微信的策略是每隔 50 毫秒获取一次主线程堆栈,保存最近 20 个主线程堆栈。这个会增加 3% 的 CPU 占用,内存占用可以忽略不计。当检测到卡顿时,最近的、最耗时的堆栈会附带到卡顿文件中。

卡死

Matrix 检测到应用卡死被强杀,会把应用上次存活时的最后一份卡顿日志标记为卡死卡顿。