WWDC2020-[Video]Why is my app getting killed?
该session重点讲解了iOS App在后台可能被系统终止的原因
同时也介绍了自iOS 14开始,MetricKit推出了新的能力和新的数据用以诊断和通缉App在前后台被系统终止的情况,即MXForegroundExitData和MXBackgroundExitData
iOS App在后台可能被系统终止的原因有:
-
Crash
-
Watchdog
-
CPU resource limit
-
Memory footprint exceeded
-
Memory pressure exit(jetsam)
-
Background task timeout
无论App在前台还是后台被系统终止,MetricKit都提供了诊断和统计数据,
- 开发者一方面可以在程序中通过订阅
MXForegroundExitData和MXBackgroundExitData来查看 - 同时在Xcode Organizer中也可以查看,详细请参考下文
Crash
- 在Xcode Organizer中可以查看崩溃信息,同时在代码中也可以通过
MXCrashDiagnostic获取崩溃信息
Watchdog
- 在App中一些关键的状态变化时(如App启动、前后台切换),系统Watchdog会设置超时限制(20s),如果超时时间内一直没有完成(也就是App卡住),App就会被终止
- 这种问题预示着可能有死锁(如主线程中gcd sync行为)、无限循环代码逻辑(如无限递归调用)
- 模拟器场景,或者连接debugger调试时不会触发Watchdog的终止行为
- 在代码中可以通过
MXCrashDiagnostic查看是否存在Watchdog终止App的情况
CPU resource limit
- 当在在后台App持续消耗过高CPU资源时,系统会记录CPU异常信息
- Xcode Organizer中可以查看,对应着Energy
- 代码中可以通过MXCPUExceptionDiagnositic获取信息
- 同时异常此时也会记录到MXBackgroundExitData中
Memory footprint exceeded
-
如果要适配iPhone 6s以前的设备,要保证App的内存占用不要超过200MB
-
当App进入后台,为尽可能降低系统因其他应用内存占用而把我们App杀死的可能性,最好让我们App内存占用降低到50MB以下
-
App在一些关键的过渡过程中(如启动、前后台切换),如果耗时过长(超过大概20s)Watchdog会终止App
- 注意,当App连接debugger时,是不会被Watchdog终止的
Memory pressure exit(jetsam)
-
当应用在后台时,其他应用占用了太大内存,系统为了给其他在前台的App足够的内存空间,会把在后台的应用杀死,也叫做被系统(丢弃)jetsam了
-
jetsam事件并不意味着App有bug,这是系统的行为,但却预示着在前台的App占用过多的内存
-
如果我们的App被系统jetsam了该怎么办
- 在App进入后台时保存好状态信息,如View Controller Stack、Draft input、Media playback position
- 使用UIKit State Restoration相关的API,App即使被jetsam了,也会很快恢复到原来的样子
- App在后台时尽量保持内存占用在50MB以下,被终止的概率会下降,但系统并不保证一定不会终止
Background task timeout
- 对于短暂的且重要的后台任务(通过UIApplication.beginBackgroundTask执行的),如果没有执行endBackgroundTask或者任务时间太长,都会导致超时,超时时间大概30s,时间到达后,任务还未结束(endBackgroundTask),App就会被系统杀死。如果超时时间内结束,则可以正常的进入suspended状态
- 把每个任务看做只有30s的炸弹的导火线,一旦App到了后台,导火线就被点燃了
- 如果希望后台任务有更长的时间处理则要用
Background Tasks框架 - 关于iOS App进入后台后会发生什么可以参考--iOS App进入后台时会发生什么根据官方文档(Extending your app's background exec - 掘金