MetricKit2.0 总结
MetricKit2.0 的新功能
MetricKit 会将过去 24 小时内收集的性能数据合并,在下一次 App 启动时,通过 delegate 方法回调给我们。
MetricKit1.0 知识请参考 iOS13+ 性能和耗电量信息收集框架
以下均为 MetricKit2.0(iOS14) 新增功能.
1. MXMetricPayload
返回新增三个指标
1.1 cpuMetrics.cumulativeCPUInstructions
1 | @property (readonly, strong, nonnull) NSMeasurement<NSUnit *> *cumulativeCPUInstructions API_AVAILABLE(ios(14.0)) API_UNAVAILABLE(macos, tvos, watchos); |
新增指标, CPU执行指令数, 衡量 App 整体负荷, 参考值为 “100 kiloinstructions” (单位 千指令).
1.2 animationMetrics.scrollHitchTimeRatio
1 | @property (readonly, strong, nonnull) NSMeasurement<NSUnit *> *scrollHitchTimeRatio; |
滑动卡顿率, 滚动卡帧时间与滚动时间之比.
为了量化卡顿,引入两个指标:
1.卡顿时间:某一帧比预期展示的时间晚了多少毫秒 scrollHitchTime
, 单次滚动卡顿时间总是 16.66或者8.33ms 的整数倍.
2.卡顿率:总的卡顿时间/总时间 scrollHitchTimeRatio
, 卡顿率即为平均每秒卡顿时间, 范围为 0~1000ms/s.
卡顿率 | 标准值 |
---|---|
> 10 ms/s | 图像帧被频繁地丢弃,严重卡顿 |
5~10 ms/s | 每隔几秒会有图像帧被丢弃,轻微卡顿 |
<5 ms/s | 滑动流畅 |
之所以不用帧率 FPS 主要是两个原因:
- 当 App 闲置时, 屏幕不刷新帧率就会很低.
- 部分场景会设置帧率低于最大帧数, 比如 30 帧游戏, 视频 24 帧, 时钟Icon保持 10 帧以节省性能等.
1.3 applicationExitMetrics
1 | //新增的应用程序退出指标, 前台退出和后台退出分开统计 |
MXForegroundExitData
应用在前台退出包含的信息:
字段 | 备注 |
---|---|
cumulativeNormalAppExitCount | 正常退出应用的累计次数, 例如在多任务切换器中上划退出 |
cumulativeMemoryResourceLimitExitCount | 超过内存上限被终止的累计次数 |
cumulativeBadAccessExitCount | 访问非法地址被终止的累计次数 |
cumulativeAbnormalExitCount | 非正常退出造成崩溃的累计次数 |
cumulativeIllegalInstructionExitCount | 指令无法被 CPU 识别造成崩溃的累计次数 |
cumulativeAppWatchdogExitCount | 看门狗(死锁/死循环/主线程一直无法完成任务)终止应用的累计次数 |
MXBackgroundExitData
应用在后台退出包含的信息:
字段 | 备注 |
---|---|
cumulativeNormalAppExitCount | 正常退出应用的累计次数, 例如在多任务切换器中上划退出 |
cumulativeMemoryResourceLimitExitCount | 超过内存上限被终止的累计次数 |
cumulativeCPUResourceLimitExitCount | 后台长时间占用 CPU 被终止的累计次数 |
cumulativeMemoryPressureExitCount | 为其他进程腾出内存被终止的累计次数 |
cumulativeBadAccessExitCount | 访问非法地址被终止的累计次数 |
cumulativeAbnormalExitCount | 非正常退出造成崩溃的累计次数 |
cumulativeIllegalInstructionExitCount | 指令无法被 CPU 识别造成崩溃的累计次数 |
cumulativeAppWatchdogExitCount | 看门狗(死锁/死循环/主线程一直无法完成任务)终止应用的累计次数 |
cumulativeSuspendedWithLockedFileExitCount | 被挂起时访问锁定的文件或者数据库但是没有申请额外的后台执行时间释放资源导致被终止的累计次数 |
cumulativeBackgroundTaskAssertionTimeoutExitCount | 处理后台任务超时而被系统终止的累计次数 |
1.4 新增参数的意义
我们有各种渠道来统计诸如 app 流畅度/后台崩溃原因等信息, 但是在新的MetricKit2.0
中, 苹果在系统级别提供了更为详细准确的数据, 有利于我们更加精确地衡量App 的真实状态.
2. 新增 MXDiagnosticPayload
诊断信息
MXDiagnosticPayload
增加了多种与崩溃相关的诊断, 先总结下 App 可能存在那些被系统终止的原因
- 崩溃
SIGSEGV
SIGILL
断言和异常退出
- Watchdog
在应用程序启动、进入后台或再次进入前台时,出现长时间的挂起。它的时间限制在20秒左右。
死锁/死循环/一直无法完成的任务造成线程卡死.
- CPU资源限制
CPU资源限制是指后台CPU持续负载较高, 可以通过xcode organizer和MXCPUExceptionDiagnostic实现电量异常报告, 使用
BGProcessingTask
处理需要大量占用 CPU 的计算工作.
- 内存占用超标
超过内存上限被终止, 一般是内存泄露或是循环中临时变量未被及时释放等原因造成.
- Jetsam (内存压力退出)
处于后台时, 为其他应用腾出空间而被终止. 争取在后台使用少于50MB的空间, 可以在退出到后台时保存数据到磁盘, 清空 imageView, 删除缓存等.
如何从内存压力退出中恢复的建议
在进入后台时保存状态,如视图控制器堆栈、text fields中的草稿输入、媒体播放位置以及更多取决于你的业务场景。
使用UIKit状态恢复
想办法让用户意识不到应用程序被终止了。
MetrictKit2.0 新增了诊断信息, 使用方法同样是实现MXMetricManager
的代理, 跟 MetricKit1.0 得到各种指标方法类似.
1 | - (void)didReceiveDiagnosticPayloads:(NSArray<MXDiagnosticPayload *> * _Nonnull)payloads; |
MXDiagnosticPayload 包含四类诊断信息:crash/hang/cpuException/diskWriteException
2.1 MXCPUExceptionDiagnostic
CPU 异常诊断可以在 Xcode Organizer 中查看,诊断信息包含消耗的 CPU 时间、CPU 高使用率期间的总时长和消耗 CPU 时间的线程调用栈。与性能数据(Metric Payload)结合起来对于找出不易复现的回归非常有用。
字段 | 备注 |
---|---|
callStackTree | 过多消耗CPU 线程的堆栈信息 |
totalCPUTime | 此次 CPU 异常消耗的CPU时间 |
totalSampledTime | 此次 CPU 异常的采样时长 |
2.2 MXDiskWriteExceptionDiagnostic
磁盘写入异常诊断跟 CPU 异常诊断很相似,每个诊断会包含造成异常的写入总数,以及导致过多写入的线程调用栈。并且这些诊断当应用程序超过了每天 1GB 的阈值时就会生成。
字段 | 备注 |
---|---|
callStackTree | 过多写操作的堆栈信息 |
totalWritesCaused | 此次异常写入磁盘总量 |
2.3 MXHangDiagnostic
挂起是指应用程序长时间不响应用户输入的情况,可能是主线程繁忙或被阻塞。MetricKit 为我们提供应用程序无响应的持续时间以及主线程的调用栈。
字段 | 备注 |
---|---|
callStackTree | 堆栈信息 |
hangDuration | 此次异常写入磁盘总量 |
参考1 :为什么我的应用程序被杀死