最近参加ArchSummit,听字节APM线分享iOS的OOM和Watchdog等问题的治理,刚好工作也相关,收获不少,做个笔记
分类
- OOM
- Watchdog
- Crash
- Disk I/O 异常
- CPU异常
OOM
OOM问题没有明确调用栈,也很难复现,字节解决方法是MemoryGraph
- App物理内存占用超过一定值(根据实际情况设定)就会内存dump下来,
- 对各个内存节点进行符号化(SDK直接做符号化的话,系统库这部分没问题,不过APP程序符号不是strip掉了么,不过实际操作都好解决)
- 和记录彼此的强弱引用关系(通过内存地址来判断相互之间的引用关系)
- 上报到后台分析大内存占用和内存泄露问题。
常见原因:
- 内存泄露
- 内存堆积
- 资源异常
- 内存使用不当
Watchdog
方法;
-
多次抓栈并记录主线程的线程状态(其他线程也会抓,但相对主线程来说没那么频繁)
-
根据调用栈,CPU占用和状态,线程标记来判断是否存在死锁或者死循环
一般排查卡顿的确也会考虑定期从寄存器抓取线程堆栈,维护一定时间区间内的栈信息(毕竟卡顿时刻的堆栈并不一定是原因所在,所以需要是区间),再检测到卡顿时上报到后端,辅助排查。不过就是要注意性能开销,,免得检测工具本身反而成为影响性能的原因。
常见原因:
-
死锁
-
锁竞争
-
主线程IO
-
跨进程通信
Crash
方法:
- 生成coredump(常见操作,没啥好说的,有当前时刻的完整运行状态)
- iOS线上开启
Zombie Object
,就是OC对象销毁hook掉,生成僵尸对象,只要野指针指向僵尸对象,再次访问就会崩溃在那里,这样就能拿到真正的错误现场(值得注意的是,这里相当于内存没有回收掉,某种意义上的内存泄露,所以线上开启时必须要对对象的数量有限制)
CPU&Disk I/O
基于MetricKit框架获取处理(我只是一个小服务端,不大了解苹果这框架,就酱)
参考内容
- 字节ArchSummit上分享的PPT 如何系统性治理iOS稳定性问题-丰亚东