Skip to main content

Chapter 155: Energy and Thermal Debugging

Energy debugging 解决的是一个跨层归因问题:用户看到手机掉电、发热、掉帧、相机降级、后台任务延迟,开发者需要把这些现象放回 CPU、网络、定位、传感器、屏幕、系统调度和温控策略的共同时间线。能耗和温度没有单一入口,App 代码、Framework API、系统服务、内核调度、驱动状态和硬件功耗域都会改变最终曲线。

本章用一个贯穿现象组织内容:一个地图类 App 在后台保持位置更新,同时上传轨迹、维持音频导航提示,并在用户回到前台后出现短时卡顿和机身发热。读完本章后,读者应能定位能耗曲线上的峰值来自哪类资源,判断温控导致的性能下降发生在哪个系统边界,并区分 App 行为、系统策略和硬件限制各自承担的责任。

Energy debugging 的基本方法是先固定时间线,再把指标映射到责任主体。CPU time 指向线程执行,wakeups 指向唤醒频率,network bytes 指向无线传输,GPS usage 指向定位链路,display time 指向屏幕和图形链路,thermal state 指向系统已经进入温控策略。单个指标只能给出嫌疑范围,多个指标在同一时间段同时变化,才构成可复盘的系统证据。

Android 和 Apple 平台提供的工具表面不同,底层问题相同。Android 侧常见材料包括 batterystats、Battery Historian、Perfetto、Power Profiler 和厂商 Power Stats。Apple 侧常见材料包括 Xcode Organizer energy reports、Instruments Energy 相关模板、MetricKit payload、ProcessInfo.thermalState 和系统日志中的体验指标。公开资料能确认工具入口和 API 表面,私有策略的具体阈值需要按平台版本、设备型号和厂商实现保留边界。

155.1 Energy Debugging 的系统指标

Energy debugging 的第一步是建立可比较指标集。能耗现象通常先表现为电量下降,系统内部却按资源活动记录事实:CPU 执行了多少时间,进程触发了多少次 wakeup,网络传输了多少字节,定位硬件工作了多长时间,屏幕点亮了多久,温度状态是否从正常区间进入限制区间。把这些指标放在同一条时间线上,才能从“耗电”转成“哪个资源在什么时段持续活动”。

CPU time 记录进程或线程获得 CPU 执行时间的总量。它适合定位计算密集型问题,例如 JSON 解析循环、地图瓦片解码、持续加密上传、前台动画计算。CPU time 高说明处理器正在执行指令,但它本身无法判断功耗高低,因为同样的 CPU 时间可能落在效率核、性能核、不同频率和不同温控状态下。排查时应把 CPU time 与 CPU frequency、thread scheduling、前后台状态结合阅读。

Wakeups 记录系统从低功耗等待状态被事件拉起的次数。一次 wakeup 可能来自 alarm、timer、network packet、sensor event、location callback、push delivery 或音频路由事件。wakeups 的危害在于频率,短任务即使每次只运行几十毫秒,也会阻止 CPU cluster、无线模块或整机进入更深 idle state。地图 App 后台每 5 秒上传一次轨迹,比每 60 秒合并上传更容易抬高 wakeup 密度。

Network bytes 记录移动网络或 Wi-Fi 传输的数据量。无线能耗由字节数、连接状态、信号质量、批量策略和 radio tail time 共同决定。小包频繁发送通常比同等总量的批量发送更消耗电源预算,因为蜂窝 modem 需要保持高功耗状态等待后续数据。后台轨迹上传应观察 tx bytes、rx bytes、socket 活动、网络类型、信号强度和前后台 set,Android dumpsys 文档中也把前台、后台网络统计放入可诊断输出。

GPS usage、location update 和 sensor sampling 指向持续环境感知链路。GPS 需要射频接收、基带或定位芯片、位置融合服务和应用回调共同工作;加速度计、陀螺仪、计步器可能由 sensor hub 低功耗处理,也可能把高频事件上送到主处理器。排查时要区分“硬件采样一直开着”和“App 回调频率过高”,前者由系统服务持有硬件能力,后者由 App 请求参数和生命周期策略决定。

Display time 记录屏幕点亮、亮度、刷新率和图形输出的能耗背景。前台卡顿与耗电经常同时出现,因为高刷新率、持续动画、视频预览或地图渲染会让 GPU、display engine、内存带宽和 CPU render thread 同时活跃。屏幕关闭后的后台耗电需要从 display time 中剥离,剩余曲线才更容易归因到定位、网络、音频或后台计算。

Thermal state 是温控策略已经介入的系统信号。温度升高会触发 CPU / GPU 频率下降、相机帧率或画质降级、充电限速、屏幕亮度限制、后台任务收缩和网络吞吐变化。Apple 公开 API ProcessInfo.thermalState 把运行时热状态暴露给 App,Android 也在系统、电源、性能和厂商层提供不同形式的 thermal 数据。这里要把 thermal state 当成系统策略入口,而非单纯的温度读数。

下图把本章贯穿现象中的核心指标放到责任边界上。图的目的不是画完整硬件功耗模型,而是说明一个 App 可见耗电现象如何被拆成系统可观察证据。

图中的关键点是指标归属不同。CPU time 靠近 App 线程和内核调度,wakeups 更靠近系统服务和 timer 机制,location 与 network 由系统服务代理硬件能力,thermal state 来自硬件采样和系统策略。排查顺序应从用户可见时间段开始,再向左追踪到资源活动和策略边界。

155.2 CPU Wakeup、Network Wakeup、Location Update、Sensor Sampling

移动设备的后台能耗常由多种小事件叠加形成。一次定位回调可能触发数据库写入、轨迹压缩、网络上传、通知刷新和日志落盘;每一步看起来都短,组合后会产生密集 CPU wakeup、网络 wakeup 和传感器采样。排查这类问题时,先看频率,再看每次回调后派生了哪些工作。

CPU wakeup 的核心证据是时间轴上有规律的短执行片段。它通常来自定时器、alarm、JobScheduler / WorkManager、iOS background refresh、音频回调、推送处理或网络 socket。地图 App 如果每几秒醒来计算一次速度、海拔和路径偏移,CPU 使用率未必长期很高,但 CPU idle state 会被频繁打断。Perfetto 的 CPU scheduling、CPU idle 和 CPU frequency 轨迹可以把这种“短任务密集”还原成执行片段和频率变化。

Network wakeup 的核心证据是小包、连接保持和后台传输时间与电量下降同段出现。蜂窝网络下,radio 从低功耗状态升到传输状态需要成本,传输后还会保持一段活动窗口等待后续数据。应用层看到的只是 HTTP request 或 WebSocket ping,系统侧看到的是 socket、NetworkStats、radio active、signal level 和 UID 网络归属。小包合并、上传窗口对齐、弱网退避和前后台策略,是网络能耗排查时更稳定的改动方向。

Location update 的核心证据是定位请求参数与系统位置活动相匹配。高精度定位通常会使用 GNSS、Wi-Fi、蜂窝、Bluetooth beacon 和传感器融合;低精度或低频定位可以更多依赖缓存和网络定位。App 请求“持续导航级别更新”会把硬件和服务链路维持在较高活动状态。App 请求“区域变化或低频更新”会给系统留下合并与降级空间。排查时要记录 accuracy、interval、distance filter、前后台状态、权限状态和用户可见功能。

Sensor sampling 的核心证据是采样频率和事件上送路径。计步、抬腕、运动状态识别可能在低功耗 sensor hub 内完成;高频加速度、陀螺仪或自定义运动算法可能让主处理器周期性醒来。采样频率越高,越需要关注 batching latency。较长 batching latency 允许传感器事件先在硬件或系统服务中聚合,再批量交给 App;过短 latency 会增加回调密度。

这四类 wakeup 会互相放大。位置回调触发上传,上传失败触发重试,重试计时器触发 CPU wakeup,弱网下每次传输又延长 radio active。调试时可以把一次后台轨迹同步拆成如下链路:location callback → compute segment → persist point → enqueue upload → network send → retry / ack → update notification。每个箭头都对应一个可检查的执行片段或系统统计。

Android 侧可以从 batterystatsdumpsys 和 Perfetto 同时读取证据。Android 开发者文档说明,Batterystats 收集设备上的电池数据,开发者可以通过 adb 导出,并用 Battery Historian 转成浏览器可视化报告;同一文档也提示 Battery Historian 已停止积极维护,较新的分析应优先考虑 system tracing、Macrobenchmark power metric 或 Power Profiler。这个版本边界会影响工具选择:历史报告适合做长时间概览,Perfetto 更适合做跨线程、频率和状态的时间线复盘。

常用 Android 采集命令的作用如下。命令只是材料入口,最终结论仍要回到时间线和责任主体。

adb shell dumpsys batterystats --reset
# 复现目标场景后导出统计
adb shell dumpsys batterystats --charged com.example.maps > /tmp/batterystats.txt
adb bugreport /tmp/bugreport.zip

第一条命令清空历史统计,第二条命令按充电周期导出指定包名相关统计,第三条命令生成包含更多系统材料的 bugreport。Android 文档还说明 dumpsys batterystats 的输出通常包含 battery event history、global statistics、UID 近似功耗、mobile milliseconds per packet、system UID 和 App UID 聚合统计。阅读时应把 UID 统计当成归因起点,再用 trace 细化到线程、服务和硬件状态。

Apple 侧同样要从 wakeup、location、network 和 sensor 四个方向归因。Instruments 可用于录制能耗和线程活动,Xcode Organizer 可查看真实用户侧的 energy report,MetricKit 可在 App 运行后收到按周期聚合的性能、能耗和诊断 payload。MetricKit 是公开 API 表面,具体系统如何给某个设备型号设置能耗阈值属于平台内部策略;正文后续只把它作为可观测材料,不把阈值当成固定事实。

155.3 Thermal State、Frequency Throttling 与性能下降

温控调试要把“热”拆成三个层级:硬件温度事实、系统 thermal state、策略执行结果。硬件温度事实来自电池、SoC、modem、camera、skin temperature 等传感器。系统 thermal state 是平台对这些事实的归纳状态。策略执行结果包括降频、降低刷新率、限制相机、收缩后台任务、降低网络吞吐或提示用户。开发者能稳定观察到的是后两层:thermal state 和用户可见性能变化。

Frequency throttling 是温控对性能最直接的影响。CPU / GPU 频率下降后,原来 8 毫秒完成的地图瓦片绘制可能变成 16 毫秒以上,UI thread、render thread 和 GPU command queue 的余量一起变小。此时性能下降不一定来自新代码变慢,可能来自同样工作运行在更低频率和更严格功耗预算下。Perfetto 的 CPU frequency 与 scheduling 轨迹能说明线程是否仍在运行,frequency track 能说明系统是否降低了计算资源上限。

Thermal state 进入限制区间后,系统会优先保护设备安全、握持温度和电池健康。用户看到的是前台帧率下降、相机预览变暗或帧率降低、视频录制中断、5G 吞吐下降、充电速度变慢,开发者看到的是任务耗时上升和回调延迟。把这些现象放在同一条时间线上,才能区分“App 算法复杂度上升”和“系统资源上限下降”。

地图 App 的温控路径可以这样复盘:用户打开导航,屏幕高亮、GPS 持续定位、地图渲染持续刷新、语音提示占用音频链路、弱网下持续上传轨迹;SoC、modem 和 display 同时处于活动状态;温度上升后 CPU/GPU 频率下降;回到前台时地图渲染和轨迹重算落在受限频率下,于是出现卡顿。这里的责任链横跨 App 行为、Framework 请求、位置服务、网络服务、图形栈、内核调度和 thermal policy。

Apple 平台公开提供 ProcessInfo.thermalState,常见状态包括 nominal、fair、serious、critical。App 读到 serious 或 critical 时,应主动降低工作强度,例如减少动画刷新、降低推理频率、暂停非用户可见批处理、延后上传或降低相机/图形质量。该 API 给的是平台归纳状态,不暴露具体传感器阈值。正文判断只依赖公开状态,不假设私有 thermal daemon 的内部规则。

Android 侧 thermal 证据分散在 Perfetto、system trace、dumpsys、Power HAL、厂商 stats 和系统日志中。Perfetto 文档说明,CPU frequency 与 idle state 可通过 ftrace 事件或 sysfs polling 记录;在多数 Android 设备上,frequency scaling 常按 big/little cluster 分组出现。这个事实帮助我们把“线程排队”与“频率上限下降”分开:线程一直 runnable 但频率降到较低档位,结论应指向 thermal 或 power policy;线程长期 sleeping 或 blocked,则应继续追踪锁、I/O、Binder 或网络等待。

温控排查的判断顺序可以固定为四步。先看用户可见症状出现的绝对时间段,例如 14:03 到 14:08。再看同段 thermal state、CPU/GPU frequency、display brightness、camera/network 活动是否变化。接着看 App 工作量是否同步增加,例如导航开始、视频录制开始、地图样式切换或模型推理启动。最后比较频率下降前后的任务耗时,把“工作变多”和“资源上限下降”分开。

一个稳定的结论要能说明触发条件和降级动作。比如“导航开始后三分钟,GPS、network tx、display on、render thread 和 CPU freq 同段活跃;随后 thermal state 升高,CPU cluster frequency 下降,frame deadline miss 增多;首要改动是降低后台上传频率,并在 serious thermal state 下减少地图重绘和轨迹压缩频率”。这个结论同时覆盖材料、原因、边界和改动方向。

155.4 Android Battery Historian、Perfetto、Power Stats

Android 能耗调试应把工具分成三类:长时间聚合、短时间 trace、设备/厂商功耗状态。Battery Historian 和 batterystats 适合看充电周期或复现场景中的 UID 活动概览;Perfetto 适合看线程、进程、CPU frequency、idle、wakelock、frame timeline 和系统服务事件;Power Stats 或厂商电源轨数据适合看硬件域活动。三类材料的时间粒度不同,结论需要按同一复现窗口对齐。

batterystats 的优势是 UID 归因和电池相关事件历史。Android 官方 dumpsys 文档说明,batterystats 服务会按 UID 组织设备电池使用统计,并且输出通常包含 battery-related events、device global statistics、per-UID approximate power use、mobile milliseconds per packet 等内容。对地图 App 来说,这能回答“这个包名在复现场景中是否明显参与耗电”,以及“前后台网络、传感器、wakelock、job、alarm 是否集中出现”。

Battery Historian 的优势是把 batterystats 或 bugreport 转成可视化时间线。Android 文档明确说明,Battery Historian 的 chart 会按时间显示 power-relevant events,每一行显示系统组件活动区间;同页也强调 chart 表示组件是否 active,并不直接显示该组件消耗了多少电量。这个边界很重要:看到 GPS 行活跃,只能说明定位链路处于活动区间;要判断电量影响,需要结合 UID stats、CPU、网络、屏幕、温控和复现动作。

Perfetto 的优势是跨层细粒度时间线。它可以把 App 主线程、render thread、Binder call、system_server、CPU scheduling、CPU frequency、idle state、frame timeline 和自定义 trace event 放在同一视图。对 Energy debugging 而言,Perfetto 适合回答“某个 wakeup 后到底执行了哪些线程”“温控后 CPU 频率是否下降”“frame miss 是否发生在频率下降之后”“网络回调是否触发了密集数据库写入”。

Power Stats 的角色是把硬件域状态纳入证据链。不同设备暴露的电源轨、component energy、rail energy 或 vendor stats 不完全一致,读者不应假设每台 Android 设备都有同样字段。能够读取时,Power Stats 可以说明 CPU cluster、GPU、display、modem、Wi-Fi、camera 等硬件域的活动占比;无法读取时,也可以用 CPU frequency、network bytes、display time、camera state 和 thermal state 作为替代证据。

Android 复盘一个后台耗电问题时,可以采用一条固定材料链。先用 batterystats 或 bugreport 确认 UID 与时间窗口;再用 Perfetto 抓一段可复现 trace;再补充 Power Profiler 或 Power Stats;最后把 App 业务日志中的导航开始、上传开始、位置回调和前后台切换打到同一时间轴。业务日志需要记录动作时间;只有“开始导航”这种无时间戳事件,无法完成跨工具对齐。

下面的 Mermaid 图展示 Android 能耗材料之间的关系。图的边界是调试材料,不代表 Android 内部完整电源架构。

图中的阅读顺序从 App 复现动作开始。先确认统计窗口,随后把聚合统计、细粒度 trace、硬件功耗估计和业务阶段对齐。只看 UID 聚合容易漏掉线程阻塞和频率下降;只看 Perfetto 容易失去长时间电池背景;只看 Power Profiler 容易缺少业务动作。三者合并后,才可以把“耗电峰值”改写为“某个业务阶段驱动了某组系统资源”。

一个 Android 结论示例可以这样写:com.example.maps 在后台导航期间产生周期性 location callback;每次 callback 后 200 毫秒内出现数据库写入和 HTTPS 上传;batterystats 显示后台网络和 wakeup 集中在同一窗口;Perfetto 显示 CPU cluster 无法进入较深 idle,弱网重试扩大了 radio 活动时间;优化方向是合并位置点、拉长上传窗口、弱网退避,并在前后台切换时重新计算定位精度。

155.5 Apple Energy Log、Instruments、MetricKit Thermal / Energy Metrics

Apple 平台的能耗材料分为本地录制和线上聚合两类。本地录制侧,Instruments 用于观察当前设备上的 CPU、线程、网络、文件、图形、能耗和系统活动;Xcode Organizer energy reports 用于查看来自用户设备的聚合体验;MetricKit 用于让 App 接收性能、能耗和诊断 payload。三类材料共同回答“现场发生了什么”“用户群体中是否普遍发生”“App 能否在代码内拿到聚合反馈”。

Energy Log 或 Instruments 能回答局部复现问题。开发者在本地设备上复现导航、后台定位、上传和回前台卡顿,可以观察 CPU activity、network activity、wakeups、thread state、signpost、thermal state 变化和 UI 响应。Instruments 的价值在于把用户动作和系统活动叠在同一条时间线上;它给出的结论仍需要结合业务阶段解释,例如“开始导航后每次位置回调触发一次轨迹压缩和上传”。

MetricKit 能回答线上聚合问题。MetricKit 通过 MXMetricManager 向 App 交付 metric payload 和 diagnostic payload,公开文档入口包括 MetricKitMXMetricPayload。这些 payload 可以覆盖 CPU、memory、disk I/O、network transfer、display、hang、crash 等维度,具体可用字段随系统版本和平台能力变化。把 MetricKit 数据用于能耗分析时,应保留“按周期聚合、按设备和系统版本差异变化”的边界。

Thermal state 是 Apple 能耗调试中的主动降级信号。ProcessInfo.thermalState 暴露当前进程可见的热状态,App 可以在状态升高时降低工作强度。地图 App 收到 serious 或 critical 状态时,可以降低地图动画刷新、暂停非必要轨迹压缩、拉长上传间隔、降低传感器采样频率或暂缓离线地图解压。这样做会把 App 行为提前纳入系统温控策略,减少系统强制降频后集中暴露的卡顿。

MetricKit 的 thermal / energy 指标适合做相关性分析。比如某个版本上线后,后台导航用户的 energy report 升高,同时 hang diagnostic 增多,且 session 多发生在长时间导航场景。这个材料无法直接证明某行代码导致热降频,但可以提示排查方向:看该版本是否改变了位置回调频率、网络上传批量、地图渲染刷新或音频提示策略。线上聚合先定位版本与场景,本地 Instruments 再复现细节。

Apple 平台内容需要明确公开边界。公开 API 能说明 App 可以读取 thermal state、接收 MetricKit payload、使用 Instruments 和 Organizer 观察指标;系统内部 daemon 如何计算热状态、如何选择具体限频档位、如何给不同机型设置阈值,属于公开资料无法稳定展开的实现。工程写作中应把“公开可见状态”和“合理推断的系统策略”分开,结论只依赖可观察证据。

一个 Apple 结论示例可以这样写:长时间导航后,MetricKit 显示该版本在后台定位场景中 CPU 与 network transfer 指标升高,并伴随部分 hang diagnostic;本地 Instruments 复现显示位置回调后连续触发轨迹压缩、文件写入和上传,thermal state 升高后 UI 响应时间增加;改动方向是用 signpost 标记每个业务阶段,降低 serious thermal state 下的重绘和上传频率,并把后台定位精度与用户可见导航状态绑定。

155.6 Background Task、Push、Network、Audio 对能耗的影响

后台能耗的核心问题是系统需要在用户价值、续航、隐私、网络公平性和设备温度之间取舍。Background task、push、network 和 audio 都能让 App 在非前台状态继续工作,但每一种能力都有系统边界。调试时不能把后台活跃简单归为“系统限制”,应说明哪个后台能力被使用、谁授予执行窗口、触发了哪些硬件资源、用户能看到什么结果。

Background task 是受控执行窗口。Android 的 JobScheduler、WorkManager、Foreground Service、Doze、App Standby、Battery Saver 会共同影响后台执行;iOS 的 BackgroundTasks、background URLSession、location background mode、audio mode、VoIP push 等能力也有用途边界。任务被延迟时,可能是系统为了电量和温度收缩后台预算;任务持续耗电时,可能是 App 在执行窗口内触发了过多 CPU、网络或定位工作。

Push 是后台唤醒入口。普通通知 push 主要用于用户提示,data push 或 silent push 可能触发短执行窗口。推送频率过高会形成 wakeup 密度,推送后如果立即做网络拉取、数据库更新、图片解码和通知刷新,能耗会超过 push 本身。排查时应把 push receive、业务处理、网络请求和通知展示放在同一条时间线上,判断 wakeup 后派生工作是否过多。

Network 是后台能耗的放大器。后台网络有三个典型问题:频繁小包、弱网重试、连接保活。地图 App 的轨迹上传如果每个点单独发送,会让无线模块频繁进入活动状态;弱网下重试策略过短,会把同一批数据反复传输;长连接 ping 间隔过短,会让后台长期保持网络 wakeup。稳定做法是合并上传、指数退避、按网络类型调整策略,并让用户可见功能决定实时性等级。

Audio 是合法后台活跃能力之一,也会改变系统策略。导航语音、音乐播放、通话、录音都可能让 App 在后台保持一定活动。音频链路涉及 audio session、route、codec、DSP、speaker / Bluetooth 和中断策略。后台音频场景中,CPU wakeup、network streaming、Bluetooth 连接和音频 buffer 回调可能叠加。排查时要区分“音频播放本身需要持续能力”和“音频回调中附带了无关计算或网络任务”。

后台定位是移动 OS 中最容易产生耗电争议的能力。持续导航、运动记录、打车行程、儿童手表或安全类功能确实需要位置更新;普通内容推荐、附近信息刷新或粗略统计通常可以接受低频、区域变化或前台更新。系统服务会根据权限、前后台状态、用户设置、电量状态和平台版本调节更新频率。App 层应把业务价值写进请求参数:精度、间隔、距离阈值、后台模式和停止条件。

把四类后台能力合在一起看,排查重点是“谁触发了谁”。后台任务拉起网络,网络失败触发 push 重试,push 后刷新通知,通知更新又读取位置或文件,这样的链路会把多个系统服务同时拉起。一个高质量能耗结论应写出触发链;“后台耗电高”只能算现象描述。例如“silent push 唤醒后立即启动轨迹同步,弱网下 10 秒退避不足,导致 20 分钟内形成高频 network wakeup;同期 audio navigation 保持后台活动,定位回调继续生成上传输入”。

155.7 从能耗曲线定位系统策略问题

从能耗曲线定位问题时,第一步是划定时间窗口。用户反馈“从下午两点开始很耗电”没有足够精度,调试需要转换成复现窗口:14:00 打开导航,14:03 进入后台,14:10 进入弱网,14:18 回到前台,14:20 设备明显发热。所有工具材料都要对齐到这个窗口,超出窗口的统计只能作为背景。

第二步是区分曲线形态。平滑上升通常指向持续活动,例如屏幕常亮、GPS 常开、音频播放或网络 streaming;锯齿状峰值通常指向周期性 wakeup,例如 timer、push、sensor batch flush 或上传重试;前台切换后突然峰值通常指向恢复路径,例如缓存重建、地图重绘、数据库同步或图片解码;温度上升后性能下降通常指向资源上限被系统策略压缩。

第三步是按资源层级归因。App 层看业务阶段和线程;Framework 层看 API 请求参数和生命周期;系统服务层看位置、网络、音频、通知、后台任务的所有权;内核层看 scheduling、wakelock、CPU frequency、idle state;驱动和硬件层看 modem、display、GPS、camera、thermal sensor 和 power rail。每一层都只能回答自己的问题,跨层结论需要把证据串起来。

第四步是把系统策略写入结论。系统策略问题不是“系统有 bug”的同义词,它可能是 App 请求参数让系统按高功耗路径执行,也可能是平台在热限制下主动降级,也可能是后台配额按预期收缩导致任务延迟。能耗曲线上的策略点通常表现为 Doze / App Standby 生效、后台任务延迟、Foreground Service 提升优先级、thermal state 上升、CPU/GPU 频率下降、网络批量窗口变化或定位精度降级。

第五步是验证改动方向。降低 CPU 算法复杂度只会影响 CPU time;合并上传会影响 network wakeup 和 radio active;降低定位精度会影响 GPS usage;减少动画刷新会影响 display / GPU;响应 thermal state 会影响严重发热后的性能稳定性。一个改动应对应一个指标变化。多个改动同时上线会降低归因清晰度,因此能耗优化更适合按资源链分批验证。

下面给出本章贯穿现象的完整复盘模板。它把用户可见现象、系统材料和责任边界压缩成一个可迁移判断顺序。

这条序列说明,能耗问题需要从用户动作开始,也要回到用户结果。App 的请求进入 Framework,系统服务持有定位、网络和音频资源,Kernel 调度线程和唤醒,硬件活动推动热状态上升,系统策略再把回调延迟、频率下降或资源降级返回到 App。最终用户看到的“卡顿发热”是整条链路共同输出。

本章的最终判断顺序可以固定为:先圈定时间窗口,再找资源峰值,再定位触发链,再识别策略点,最后把改动映射到指标。对 Android,常用组合是 batterystats / Battery Historian 做窗口和 UID 概览,Perfetto 做线程、频率和 wakelock 复盘,Power Profiler 或 Power Stats 做硬件域补证。对 Apple,常用组合是 Instruments 做本地时间线,MetricKit 和 Organizer 做线上聚合,ProcessInfo.thermalState 做运行时降级输入。

最小自检任务

一个运动记录 App 在后台运行 40 分钟后,用户反馈电量下降明显,回到前台后地图页面卡顿 10 秒。已知现象包括:后台每 5 秒收到一次位置回调,每次回调都会写数据库并尝试上传;弱网下上传失败后 10 秒重试;应用保持语音提示能力;设备在 25 分钟后进入较高 thermal state。请按 App → Framework → 系统服务 → 内核/驱动 → 硬件/策略的顺序写出排查路径,并说明首批应该验证的三个改动方向。

答案要点

App 层先标记时间窗口和业务阶段:开始记录、退到后台、位置回调、数据库写入、上传、弱网重试、回到前台。Framework 层检查定位请求参数、后台模式、网络任务配置和音频会话,判断这些请求是否要求系统持续保留高频能力。系统服务层检查 location、network、audio、background task 的活动是否同段出现,重点看 5 秒定位回调是否驱动网络上传和重试。内核/驱动层检查 CPU wakeup、wakelock、CPU frequency、idle state、network bytes、radio active 与 frame miss。硬件/策略层检查 thermal state 上升后是否出现 CPU/GPU 频率下降、回调延迟或前台绘制耗时增加。

首批改动方向应对应三个资源链。第一,合并位置点并拉长后台上传窗口,弱网下使用指数退避,用 network wakeup、tx bytes 和重试次数验证。第二,根据前后台状态和 thermal state 降低定位精度或回调频率,用 GPS usage、location callback 密度和 CPU wakeup 验证。第三,回到前台时分批恢复地图重绘和轨迹计算,用 frame time、CPU frequency、render thread 耗时和 thermal state 验证。语音提示能力可以保留,但音频回调中不应夹带轨迹压缩和网络上传等无关工作。

本章知识点总结

  • 指标集合:能耗排查需要同时观察 CPU time、wakeups、network bytes、location、display time 和 thermal state。
  • 时间窗口:所有结论都应绑定复现窗口,脱离窗口的累计统计只能提供背景。
  • 唤醒密度:短任务频繁唤醒会阻止系统进入更深 idle state,低 CPU 占比也可能形成高能耗。
  • 网络批量:后台小包、弱网重试和连接保活会放大无线模块活动时间。
  • 定位链路:定位能耗由精度、间隔、距离阈值、前后台状态和系统融合策略共同决定。
  • 传感器采样:采样频率和 batching latency 决定事件是在低功耗硬件中聚合,还是频繁唤醒主处理器。
  • 温控分层:温控排查要区分硬件温度事实、系统 thermal state 和策略执行结果。
  • 降频证据:线程仍然 runnable 且 CPU/GPU frequency 下降时,性能下降应纳入 power 或 thermal policy 判断。
  • Android 材料batterystats 适合 UID 聚合,Battery Historian 适合长时间可视化,Perfetto 适合跨线程和频率复盘,Power Stats 适合硬件域补证。
  • Apple 材料:Instruments 适合本地时间线,MetricKit 和 Organizer 适合线上聚合,ProcessInfo.thermalState 适合作为运行时降级输入。
  • 后台能力:Background task、push、network、audio 和 location 都应按触发链分析,不能把后台活跃归成单点问题。
  • 策略归因:Doze、后台配额、thermal state、频率限制和定位降级都是系统策略点,结论要说明触发条件与用户可见结果。
  • 改动验证:每个优化动作都要映射到一个或一组指标,例如 wakeup、network bytes、GPS usage、frame time 或 thermal state。