引言
本文将循着微信iOS卡顿监控系统的思路:起一个子线程,监控主线程的活动情况,如果发现有卡顿,就将堆栈 dump 下来。做一个简单的deom,体验一把。
Coding
废话少说,直接撸代码。首先创建一个NSThread的子类BWKPingThread。
.h文件
一个简单的初始化方法,入参为卡顿监测的时间阈值,超过该阈值即上报卡顿。
1 | - (instancetype)initWithThreshold:(NSInteger)threshold; |
.m文件
类拓展
在类拓展中声明三个属性:
- threshold:存储卡端监测时间阈值
- pingSemaphore:用于卡端监控的信号量
- runloopObserver:用于监控主线程runloop的observer
1 | @interface BWKPingThread() |
init方法 & addRunloopObserver方法
初始化工作,添加observer观测主线程runloop,在没一个runloop回调中调用dispatch_semaphore_signal()自增信号量。
1 | - (instancetype)initWithThreshold:(NSInteger)threshold{ |
main方法
重写NSThread的main方法,调用dispatch_semaphore_wait()等待信号量的释放,如果等待时间超过阈值,则监测到主线程阻塞、上报卡顿。
1 | - (void)main |
cancel方法
重写cancel方法,移除observer
1 | - (void)cancel |
测试代码
我们在主线程中创建pingThread,并通过模拟耗时操作阻塞主线程以测试卡顿监测。
1 | BWKPingThread * pingThread = [[BWKPingThread alloc] initWithThreshold:1]; |
通过控制台log可以看到成功监测到卡顿
1 | 2018-04-21 21:20:20.309915+0800 Ping_Demo[98239:5860372] The main thread is blocked. |
卡顿堆栈?
这里推荐一个三方库plcrashreporter。通过plcrashreporter可以拿到所有线程堆栈,国内很多Crash上报平台都是通过plcrashreporter实现的。