最近参加ArchSummit,听字节APM线分享iOS的OOM和Watchdog等问题的治理,刚好工作也相关,收获不少,做个笔记

分类

  • OOM
  • Watchdog
  • Crash
  • Disk I/O 异常
  • CPU异常

OOM

OOM问题没有明确调用栈,也很难复现,字节解决方法是MemoryGraph

  1. App物理内存占用超过一定值(根据实际情况设定)就会内存dump下来,
  2. 对各个内存节点进行符号化(SDK直接做符号化的话,系统库这部分没问题,不过APP程序符号不是strip掉了么,不过实际操作都好解决)
  3. 和记录彼此的强弱引用关系(通过内存地址来判断相互之间的引用关系)
  4. 上报到后台分析大内存占用和内存泄露问题。

常见原因:

  • 内存泄露
  • 内存堆积
  • 资源异常
  • 内存使用不当

Watchdog

方法;

  1. 多次抓栈并记录主线程的线程状态(其他线程也会抓,但相对主线程来说没那么频繁)

  2. 根据调用栈,CPU占用和状态,线程标记来判断是否存在死锁或者死循环

一般排查卡顿的确也会考虑定期从寄存器抓取线程堆栈,维护一定时间区间内的栈信息(毕竟卡顿时刻的堆栈并不一定是原因所在,所以需要是区间),再检测到卡顿时上报到后端,辅助排查。不过就是要注意性能开销,,免得检测工具本身反而成为影响性能的原因。

常见原因:

  • 死锁

  • 锁竞争

  • 主线程IO

  • 跨进程通信

Crash

方法:

  • 生成coredump(常见操作,没啥好说的,有当前时刻的完整运行状态)
  • iOS线上开启Zombie Object,就是OC对象销毁hook掉,生成僵尸对象,只要野指针指向僵尸对象,再次访问就会崩溃在那里,这样就能拿到真正的错误现场(值得注意的是,这里相当于内存没有回收掉,某种意义上的内存泄露,所以线上开启时必须要对对象的数量有限制)

CPU&Disk I/O

基于MetricKit框架获取处理(我只是一个小服务端,不大了解苹果这框架,就酱)

参考内容