前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS卡顿监控方案浅析

iOS卡顿监控方案浅析

作者头像
用户5521279
发布2020-05-27 15:53:07
1.3K0
发布2020-05-27 15:53:07
举报
文章被收录于专栏:搜狗测试搜狗测试

背景

最近,小编一直致力于解决一项性能问题,那就是iOS输入法输入卡顿问题的监控,通过一段时间的调研,小编整理出来了一些监控方法,这里就分享给大家,希望可以给正在进行这方面工作的测试同学一点帮助。

卡顿原因

首先,我们需要明确一个定义,就是卡顿是什么?

  • 死锁:主线程拿到锁A,需要获得锁B,而同时某个子线程拿了锁 B,需要锁A,这样相互等待就死锁了。
  • 主线程大量IO:主线程为了方便直接写入大量数据,会导致界面卡顿。
  • 主线程大量计算:算法不合理,导致主线程某个函数占用大量 CPU。
  • 大量的UI绘制:复杂的UI、图文混排等,带来大量的UI绘制。
  • 主线程等待其它线程:用户进行操作后其它线程进行较复杂计算导致结果没有迅速给到主线程进行页面刷新,用户就会存在等待情况造成卡顿反馈。

方案设计

针对以上问题,我们需要什么手段去进行排查呢?这里想到的就是将当前的线程栈进行捕捉,这样我们就可以找到当前卡顿在哪一行函数。所以,这里监控卡顿的整体思路就是起一个子线程,去监控你所需要关注的线程(例如主线程)的活动情况,如果发现有卡顿,就将当前堆栈dump下来。

上图可以看出,我们在这次监控卡顿的工具中主要监控的是线程RunLoop的超时情况,由于在iOS中线程的事件处理主要依靠的是RunLoop,如果单次RunLoop运行循环的事件超过某一时间,那就会产生出用户体验卡顿情况。正常RunLoop运行循环一次的流程如下所示:

从这个运行循环中可以看出,RunLoop休眠的事件是无法衡量的,处理事件的部分主要是在kCFRunLoopBeforeSources之后到kCFRunLoopBeforeWaiting之前和kCFRunLoopAfterWaiting之后和运行循环结束之前这两个部分。那我们重点监控时间也就是这两个部分的执行时间。接下来会为大家附上具体代码进行介绍。

具体方法

对于这两个部分的耗时监控,我们可以使用CFRunLoopObserverRef来对RunLoop的状态进行超时监测。

使用信号量dispatch_semaphore来控制对RunLoop状态判断的节奏,这个可以保证每个RunLoop状态的判断都会进行。对RunLoop状态的判断,我们专门在另外一个线程做判断。

这里我们使用了一个死循环在另一个线程中去监控待测线程的RunLoop状态,其中需要注意的是blockInterval是我们这边配置的卡顿阈值,如果设定200ms则填写200即可,如果超过阈值时间后,当前状态还是没有发生变化则会返回semaphore不等于0,此时我们会进行判断,如果当前的RunLoop状态为kCFRunLoopBeforeSources或kCFRunLoopAfterWaiting,则认为此时出现了线程卡顿,我们在超时的代码块中去填写需要执行的方法,例如内存堆栈的打印,卡顿次数的统计等等。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 搜狗测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档