APP在后台被系统杀死的六种主要原因

主要介绍在APP在后台被系统杀死的六种主要原因,源自WWDC视频, 并且告诉你怎么使用MetricKit框架去发现和减少程序被强制杀死的概率;怎么防止崩溃;怎么使用后台机制,怎么找到潜在的问题并采取行动去修复。

app在后台被终止的原因

  • 崩溃(Crashes)
  • 看门狗(Watchdog)
  • CPU资源限制(CPU resource limit)
  • 内存超出系统限制(Memory limit exceeded)
  • 内存自动清理(Memory pressure exit)
  • 后台任务超时(Background task timeout)

使用MetricKit 框架收集的类型

cumulativeNormalAppExitCount:正常退出次数
cumulativeMemoryResourceLimitExitCount:内存OOM引起程序退出次数
cumulativeCPUResourceLimitExitCount:cpu资源超限引起退出次数
cumulativeMemoryPressureExitCount:系统内存自动清理引起退出次数
cumulativeBadAccessExitCount:非法访问(SIGSEGV/SIGBUS)引起退出次数
cumulativeAbnormalExitCount:Abort函数中止引起退出次数
cumulativeIllegalInstructionExitCount:非法指令(SIG)引起退出次数
cumulativeAppWatchdogExitCount:看门狗(WatchDog)引起的退出次数
cumulativeSuspendedWithLockedFileExitCount:后台读写文件引起的退出次数
cumulativeBackgroundTaskAssertionTimeoutExitCount:后台任务超时引起的退出次数

一. carsh

 解决方案: 这里大多数代码问题,请参考常规的carsh解决方案,查看日志等. 

MetricKit 可以通过编程方式从设备获取崩溃信息,MXCrashDiagnostic 包含了追踪崩溃及其他终止类型所需的所有内容。

二. Watchdog

在 app 关键切换期间长时间挂起等待, 比如说打开APP、切到后台、即将进入到前台

这3种切换有大概 20 秒的时间限制 如果附加了调试器 是不会发生这种终止情况的; 出现看门狗 通常意味着发生了严重问题 .比如说

1.死锁、
2.无限循环
3.在主线程上发生的其他无限同步工作

解决方案

使用Xcode查看和导出崩溃日志 使用 MXCrashDiagnostic 获取(见崩溃)

三. CPU resource limit(CPU资源限制)

发生CPU资源限制被系统终止的可能原因

后台长时间占用CPU资源过高(High sustained CPU load in background), 可以通过 MXCPUExceptionDiagnostic 查看。

四. Memory limit exceeded(内存超出系统限制)

 如何查看原因

后台的中央处理器内存占用持续很高时 , 系统会生成一份能量例外报告. 如果此持续性工作的时间长到一定程度 ,系统会终止 app 的运行 ;如果内存占用太多, 系统会在内存占用率超过界限值时 马上终止 app 的运行, 前台和后台的占用率界限值一样.

可以在 Xcode Organizer 中查看 中央处理器的资源例外日志 也能通过 MXCPUExceptionDiagnostic 查看

解决方案

这些报告包含调用栈, 以此识别出 你的 app 在终止发生时正在做什么. 也许你的代码里有漏洞 ,造成了中央处理器运行的任务过多, 修改一下就好. 但如果你需要在后台进行很高强度的工作 1.可以考虑把工作移入后台处理任务

注意 : 不同设备的界限值也不同 . 一般来说: 设备越老 界限值越低 若你的 app 的目标设备早于 iPhone 6s 就需要尽量把内存占用量 始终控制在 200MB 以下

五. 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)统计和发现

 如何解决?

  1. 从前台转到后台时 可以通过调用指令 UIApplication.beginBackgroundTask 获得额外的运行时间完成关键工作 当工作完成时 需调用 endBackgroundTask 指令
  2. 30s内结束后台任务
  3. 检查后台任务的剩余时间

只有在时间足够的前提下开启任务 时间小于5s时尽快结束任务

beginBackgroundTask && endBackgroundTask 成对使用

现有的网上大部分写法都是在进后台的时候开启一个beginBackgroundTask, 在对应的block中调用endBackgroundTask, 这样的写法是有问题的.

比如 退后台会开启任务A, 进到前台, 此时在退后台, 就会又开启任务B, 而任务A没有调用对应的endBackgroundTask, 导致beginBackgroundTask && endBackgroundTask 没有成对使用.

所以正确的做法就是在即将进入前台的时候也调一次endBackgroundTask, 这样退后台和进前台的就是成对出现了.

// APP进入后台的通知
- (void)applicationDidEnterBackgroundWithNote:(NSNotification *)note {
    [self _beginBackgroundTask];
}
 
// APP回到前台的通知
- (void)applicationWillEnterForegroundWithNote:(NSNotification *)note {
    [self _endBackgroundTaskIfNeeded];
}


- (void)_beginBackgroundTask {
    [self _endBackgroundTaskIfNeeded];
    if ( UIApplication.sharedApplication.applicationState == UIApplicationStateBackground ) {
        _backgroundTask = [UIApplication.sharedApplication beginBackgroundTaskWithExpirationHandler:^{
            [self _endBackgroundTaskIfNeeded];
        }];
    }
}

- (void)_endBackgroundTaskIfNeeded {
    if ( _backgroundTask != UIBackgroundTaskInvalid ) {
        [UIApplication.sharedApplication endBackgroundTask:_backgroundTask];
        _backgroundTask = UIBackgroundTaskInvalid;
    }
}

官方视频无法播放,但是有翻译  WWDC 2020 为什么我的app被终止了

在b站找到一个生肉. 

MetricKit使用 iOS 性能优化:使用 MetricKit 2.0 收集数据

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 应用程序被用户手动杀死,应用程序会收到 `onDestroy()` 生命周期回调函数。但是,在这种情况下,您无法阻止应用程序被杀死。因此,如果您希望在应用程序被杀死执行某些操作,例如重新启动应用程序或发送通知等,您需要使用一些其他方法。 一种方法是使用 Android 的 `Service` 组件。通过创建一个 `Service`,您可以在应用程序被杀死后在后台继续运行代码。要监听应用程序被杀死的事件,您可以在 `Service` 中实现 `onTaskRemoved()` 方法。 在 `onTaskRemoved()` 方法中,您可以执行您希望在应用程序被杀死执行的操作。例如,您可以使用 `PendingIntent` 发送一个通知,提示用户重新启动应用程序。 以下是一个示例代码片段,演示如何在 `Service` 中监听应用程序被杀死的事件: ```java public class MyService extends Service { @Override public void onCreate() { super.onCreate(); // 在此处执行任何必要的初始化操作 } @Override public int onStartCommand(Intent intent, int flags, int startId) { // 在此处执行您希望在后台运行的代码 return START_STICKY; } @Override public void onTaskRemoved(Intent rootIntent) { // 在此处执行您希望在应用程序被杀死执行的操作 super.onTaskRemoved(rootIntent); } @Override public IBinder onBind(Intent intent) { // 如果您的 Service 不提供绑定,则返回 null return null; } } ``` 请注意,使用 `Service` 可能会对设备的电池寿命产生影响。如果您希望在应用程序被杀死执行某些操作,但不需要在后台运行代码,请考虑使用 Android 的 `AlarmManager` 和 `BroadcastReceiver` 组件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值