您的当前位置:首页正文

认识iOS应用性能管理 -- 读《iOS监控编程》

2022-06-15 来源:知库网

由于自己待的小厂,没有做过APM(Application Performance Management,应用性能管理)相关的东西,被问及这方面内容的时候有些懵,于是读了下这本书,稍微补了点APM的知识。

整本书薄薄的一百多页,两天就能读完,把iOS的APM分为以下六个部分:

  1. 日志监控
  2. 崩溃监控
  3. 卡顿监控
  4. 网络监控
  5. 硬件监控
  6. 内存泄露监控

日志监控

解决的问题:

手机不连上Xcode就没法查看日志

原理:

用NSLog打的日志都进入了ASL(Apple System Log)中。ASL相当于系统存放日志的数据库。苹果提供了API可以从ASL里捞出你想要的日志。

崩溃监控

解决的问题:

QA发现崩溃后跑来找开发,结果无法重现

原理:
  1. 对于未捕获异常崩溃,利用NSSetUncaughtExceptionHandler在崩溃前的最后一刻留下遗言
  2. 对于底层信号崩溃,利用内核提供的API signal,给不同的崩溃信号设置处理函数

卡顿监控

解决的问题:

卡顿发生的很随机,且卡顿原因无法捕捉

原理:

主线程发生了卡顿,一定是在主Runloop的一次迭代中,执行了一个很长时间的任务,导致它迟迟不能干完活去休息。

  1. Runloop的解决方案
    可以利用信号量,或者定时器的方式(书中利用了信号量)。监测到卡顿后记录下调用堆栈,就可以上报服务端了。
    1.1 利用信号量
    主线程观察主Runloop的状态变化,每次状态有变化signal一个信号量。子线程开一个死循环,循环一开始wait这个信号量。在超时阈值n秒内等到信号量的话说明这次不卡,开启下次迭代。如果n秒内没等到信号量而超时,说明可能有点卡,记一笔,连续5次这样的话就算一次卡顿。
    1.2 利用定时器
    主线程观察主Runloop的状态变化,在AfterWaiting(Runloop醒来准备开始干活了)状态记录一个时间戳x,在BeforeWaiting(Runloop干完活准备去休息了)状态将时间戳x清零。子线程开启定时器,每隔0.5秒算出当前时间戳和x之间的差值,如果差值大于某个阈值则认为发生了卡顿。
  2. GCD的解决方案
    开个子线程,里面开个死循环,循环一开始子线程通过GCD扔一个block到main queue去执行,扔完自己就去睡个n秒(n为卡顿阈值)。在醒来前block要是还没被执行到的话,就认为发生了卡顿。

网络监控

解决的问题:

必须开Charles才能看到网络请求和返回。

原理:

利用NSURLProtocol拦截请求

硬件监控

解决的问题:

出现性能问题时看不到各项硬件指标

原理:

内核提供了API可以拿到CPU,内存,流量,温度等信息。
帧率FPS监控的原理:利用CADisplayLink算出某一段时间n(n >= 1)内刷新的帧数x,FPS = x / n

内存泄露监控

解决的问题:

必须要Instruments才能查内存泄露

原理:

大多数情况下,一个UIViewController被pop或dismiss后,它的view以及subviews等会很快释放。所以在一个UIViewController被pop或dismiss后的一段时间内,看看它的view以及subviews还在不在。

显示全文