备注
本文所有内容来自于Apple公司的WWDC20的视频Why is my app getting killed,如有错误,敬请指出。
内容概要
本文将主要介绍在APP在后台被系统杀死的六种主要原因,并且告诉你怎么使用
MetricKit框架去发现和减少程序被强制杀死的概率;怎么防止崩溃;怎么优雅的从不可避免的jetsams机制中恢复我们的程序;怎么找到潜在的问题并采取行动去修复。
程序被中止的六种原因
- 崩溃(Crashes)
- CPU资源限制(CPU resource limit)
- 看门狗(Watchdog)
- 内存超出系统限制(Memory limit exceeded)
- 内存自动清理(Memory pressure exit)
- 后台任务超时(Background task timeout)
使用MXBackgrounndExitData(iOS14 MetricKit)能够统计的数据
- cumulativeNormalAppExitCount:正常退出次数
- cumulativeMemoryResourceLimitExitCount:内存OOM引起程序退出次数
- cumulativeCPUResourceLimitExitCount:cpu资源超限引起退出次数
- cumulativeMemoryPressureExitCount:系统内存自动清理引起退出次数
- cumulativeBadAccessExitCount:非法访问(SIGSEGV/SIGBUS)引起退出次数
- cumulativeAbnormalExitCount:Abort函数中止引起退出次数
- cumulativeIllegalInstructionExitCount:非法指令(SIG)引起退出次数
- cumulativeAppWatchdogExitCount:看门狗(WatchDog)引起的退出次数
- cumulativeSuspendedWithLockedFileExitCount:后台读写文件引起的退出次数
- cumulativeBackgroundTaskAssertionTimeoutExitCount:后台任务超时引起的退出次数
崩溃(Crashes)
种类
- 段错误:Segmentation fault
- 非法指令:illegal instruction
- 断言和异常:Asserts and Uncaught Exception
怎么查看日志
- 使用Xcode查看和导出崩溃日志
- 使用xcode从真机导出
- 使用三方SDK抓取崩溃日志,比如
bugly,友盟,firebase,听云等等 - 使用 MXCrashDiagnostic 获取
- Stack trace(崩溃线程堆栈)
- Signal(信号量)
- Exception code(崩溃异常代码)
- Termination reason(崩溃原因)
看门狗(Watchdog)
什么是看门狗?
当你在如下API函数中处理时间超时之后就会被系统杀死,这种情况叫做看门狗
- application(:didFinishLaunchingWithOptions:)
- applicationDidEnterBackground(_:)
- applicationWillEnterForeground
发生看门狗的可能原因
- 死锁
- 无线循环
- 同步操作
怎么查看日志
- DEBUG模式下不生效
- 使用Xcode查看和导出崩溃日志
- 使用 MXCrashDiagnostic 获取(见崩溃)
CPU资源限制(CPU resource limit)
发生CPU资源限制被系统终止的可能原因
- 后台长时间占用CPU资源过高(High sustained CPU load in background)
怎么查看日志
- 使用Xcode查看
- 使用API
MXCPUExceptionDiagnostic抓取崩溃信息
怎么避免
- 修复问题代码
- 如果是强需求,建议将任务使用BGProcessingTask来完成。(夜间会运行几分钟)
内存超出系统限制(Memory limit exceeded)
原因
- APP占用内存超过阈值(App using too much memory)
- 阈值在前台和后台是一样的,但是不同设备不一样(Same limit for foreground and background)
- 越老的设备阈值越低,6S以前设备使用内存不要超过200MB(Keep in mind older devices(such as before 6S,Limit is 200MB))
怎么避免和发现
- 使用Intrumengts 和 Memory Debugger去早些发现问题(Use Intrumengts and Memory Debugger)
内存自动清理(Memory pressure exit)
介绍
- 通常不是程序问题(Not a bug with you app)
- 系统为了给其他APP内存而杀掉后台的程序机制
怎么减少被后台杀死的几率
- 尽量保证程序在后台占用内存小于50MB(Aim for less than 50MB in the background)
后台任务超时(Background task timeout)
介绍
执行后台任务时,未在30s内结束后台任务(Failure ro end the task explicitly result in termination.(in 30s))
怎么发现这种问题
- iOS14控制台会有超时任务消息打印
- 使用MXBackgrounndExitData(
iOS14 MetricKit)统计和发现
怎么避免
UIApplication.beginBackgroundTask(expirationHander)和UIApplication.endBackgroundTask(_:)配对使用- 30s内结束后台任务
- 检查后台任务的剩余时间
- 只有在时间足够的前提下开启任务
- 时间小于5s时尽快结束任务