WWDC20-Why is my app getting killed?

1,370 阅读3分钟

备注

本文所有内容来自于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查看
  • 使用APIMXCPUExceptionDiagnostic抓取崩溃信息

怎么避免

  • 修复问题代码
  • 如果是强需求,建议将任务使用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时尽快结束任务