美文网首页iOS之性能优化iOS精品文章
[iOS] 线上UI卡顿监控与符号化速度优化

[iOS] 线上UI卡顿监控与符号化速度优化

作者: ck2016 | 来源:发表于2018-02-06 17:22 被阅读110次

本文参考以下文章,做了一点优化,提升了卡顿监测的准确性,性能,符号化速度等等。
iOS实时卡顿监控深入理解RunLoopiOS版微信界面卡顿监测方案深入剖析 iOS 性能优化BSBacktraceLogger

UI卡顿检测

通过监测主runloop循环次数来判断是否发送卡顿。

什么是runloop?
runloop就是线程里的一个循环,退出该循环的条件是程序结束,程序什么时候结束自己定,类似MFC中消息循环。

为什么要有runloop?
线程保活,事件分发,线程频繁创建销毁耗资源,不希望线程频繁创建销毁。

怎么监控主runloop循环次数?
runloop循环的过程中会抛通知出来,在异步线程中创建一个runloop观察者监听这些通知即可。

怎么检测UI发生了卡顿?
监控主runloop循环次数,流畅情况下,一般循环60次,对应60帧。
假设认为掉了10帧,人眼能明显感受到卡顿,10 * 16.67 ms 约 166 ms,那么runloop超过166ms没回调通知给我的观察者,判定为卡顿,并且要“非常非常及时”获取下主线程的调用栈,栈顶的方法就是发生卡顿的方法。

看下图:这是网友根据runloop源码画的流程图

起一个线程用信号量卡着,每166ms执行一次,用个变量last记录最后一次runloop抛出来通知,如果发生166ms超时,去看 last 是什么值,如果是 kCFRunLoopBeforeSources 和 kCFRunLoopAfterWaiting,表示自己的代码发生卡顿,因为这两个通知后面处理的是 source0系统代码,source1用户代码,timer代码事件。发生了卡顿就在监控线程将其调用栈获取下来。

另外页面切换速度,FPS帧率,都跟主循环正相关,因为viewDidLoad等等事件都在主线程执行,UI也在主线程绘制。监测了主runloop,这两个指标其实可以不用在监测。

符号化

符号化就是给一个内存地址 0x00001234 找到其符号 -[ViewController viewDidLoad] 的过程,因为mach-o文件中包含了LC_SYMTAB段,该段中包含符号表。
注意,iOS系统做了优化,系统库的符号不在内存中,会提示 <redacted>

符号化参考BSBacktraceLogger所写

改进的地方有:
1.预处理所有image,记录下image中所需要的各个segment基址,image内存地址范围等等,避免每次用个for循环来查找segment基址,预处理后查找基址从 O(N) 降到 O(1),注意点:image可以动态加载,动态删除,好在iOS中不会删除,只会在APP启动时会逐渐加载,加完后image数量不会变化,如果image数量有变,那么得重新预处理一次。

2.查找一个内存地址 address 在哪一个 image 内,返回该 image 索引
由于有预处理image地址范围,并对地址排了序,qsort()排序,并且image地址不重叠,那么这里查找一个image直接用二分查找,从原来的两个for循环的O(n^2)降到了O(log n),为什么不用哈希查找是因为地址空间太大,64位下有2^64个地址,大约 16777216T,太大了存不下。

3.加缓存,缓存 (address, symbol) 地址到symbol符号结构体的二元组
使用自己实现的LRU缓存,比NSCache快4倍,文章地址:https://www.jianshu.com/p/1f8e36285539

4.监控线程只获取调用栈,另起一个线程进行符号化,相当于监控线程是生产者,其他线程是消费者,一对一生产消费模型。

优化结果:1000次符号化调用
7个栈:
优化后:50ms,,,优化前:1800ms

70个栈:
优化后:800ms,,,优化前:11800ms

那么除以1000就是一次符号化的时间,大约是 0.05ms 到 0.8ms 之间能获取到全部调用栈,提高了准确性。因为在50ms发生了卡顿,该卡顿可能在51ms消失,调用栈变化十分快,必须要在最短时间内捕捉到调用栈,才能准确,如果要在几毫秒后才捕捉到,那可能就不是发生卡顿的调用栈了,导致结果不准。

优化后的代码暂时未贴出,以后会考虑开源的。

线上UI卡顿监控结果

UI卡顿监控SDK终于上线了,灰度范围5万个用户,线上 0 崩溃。
后台已捕捉到几千处方法卡顿和卡顿调用栈(卡顿定义:UI线程超过500ms没响应判定为卡顿)
卡顿主要原因是:有代码在主线程同步请求网络,主线程读写数据库,写文件,加锁,做数据解析,数据计算等等。
修复完这些卡顿,APP流畅性将得到提升,用户体验提升。

监控SDK本身的性能消耗:(iPhone 6s, iOS 9.2 测得)
SDK启动时间:0.05 ms
SDK启动后:CPU 接近 0%,内存大约几十kb
包体积:72 kb
磁盘使用:3 kb,(一次启动数据上报流量 2 kb)
常驻线程:启动一分钟内有3个,收集完数据后,常驻线程仅1个,CPU 接近 0%

另外我还一个业务型的SDK在月活1.1亿的APP上,崩溃数只有11个。

相关文章

  • [iOS] 线上UI卡顿监控与符号化速度优化

    本文参考以下文章,做了一点优化,提升了卡顿监测的准确性,性能,符号化速度等等。iOS实时卡顿监控,深入理解RunL...

  • iOS通过runloop监控卡顿

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

  • Activity 性能优化方案

    Activity 性能优化方案UI 卡顿原理UI卡顿常见原因优化手段 UI 卡顿原理人类大脑与眼睛对一个画面的连贯...

  • 无标题文章

    APP性能优化 UI卡顿优化 View的绘制原理 UI卡顿原理分析 UI卡顿检测分析 BlockCanary原理分...

  • 卡顿检测资料

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

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

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

  • 21-性能优化

    一、CPU和GPU 二、卡顿产生的原因和优化 卡顿优化-CPU 卡顿优化-GPU 卡顿监测 监控卡顿的demo:推...

  • signal causes debugger to stop a

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

  • iOS开发进阶:性能优化与稳定性优化实践

    页面卡顿原理与优化 离屏渲染原理与优化 复杂视图的渲染优化 崩溃监控方案

  • iOS文章收录

    1、iOS如何监控界面卡顿掉帧,如何优化https://juejin.cn/post/69934852594676...

网友评论

    本文标题:[iOS] 线上UI卡顿监控与符号化速度优化

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