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

作者: njuxjy | 来源:发表于2017-03-26 12:54 被阅读251次

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

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

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

    同时配套了作者自己开源的一个APM大轮子GodEye

    日志监控

    解决的问题:

    手机不连上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还在不在。

    相关文章

      网友评论

        本文标题:认识iOS应用性能管理 -- 读《iOS监控编程》

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