1. 缓存命中率低的典型现象
当系统或应用的缓存命中率长期处于低位时,CPU、内存和I/O 子系统之间会频繁发生“缓存未命中→ 主存/磁盘加载”的慢路径操作。这种慢路径在用户端会叠加出若干可感知与可测量的性能异常。本章从工程师视角归纳这些现象,并为后续使用 Perfetto 抓取证据提供识别锚点。
1.1 现象清单与特征描述
| 现象 | 特征描述 | 排查方向 | 影响范围 |
|---|---|---|---|
| 应用卡顿 | 列表滑动不跟手、过渡动画掉帧、点击后延迟响应 | UI 线程等待内存/磁盘加载 | 前台应用 |
| 帧率抖动 | Profiler 曲线频繁出现≥ 16ms/33ms 单帧耗时尖刺 | GPU 或 SurfaceFlinger 因缓存未命中而阻塞 | 渲染管线 |
| 页面加载慢 | Activity/Fragment inflate 、网络数据解析、图片解码时间过长 | 资源缓存与对象缓存失效 | 应用冷/热启动 |
| ANR 出现 | AMS 检测到主线程超时(5s Broadcast/20s Service/200ms Input) | I/O 或内存访问堆积导致主线程阻塞 | 全局体验 |
| 系统 CPU 异常高 | CPU 使用率长时间 > 80%,且 kswapd/irq 等内核线程活跃 | 缓存未命中引发大量 TLB miss 和缺页中断 | 系统整体功耗 & 散热 |
1.2 现象关联故障树
下面的故障树展示了缓存命中率低如何逐层传导为用户侧可感知的性能症状。每层节点都对应 Perfetto 中可观测的 trace 指标。
1.3 现象-排查匹配表
在实际排查中,同一个现象可能由多个缓存层级导致。以下匹配表帮助你在选择 Perfetto 分析目标前快速收敛范围。
| 现象 | 首要怀疑层级 | 次要怀疑层级 | Perfetto 初步数据源 |
|---|---|---|---|
| 帧率抖动 | L1/L2 cache(CPU 流水线 stall) | GPU cache / System cache | CPU frequency + cache-misses 计数器 |
| 应用卡顿 | TLB / page-table walk | I/O 等待 | sched_switch + page_fault |
| 页面加载慢 | 文件系统缓存 / page cache | 应用对象缓存 | f2fs/ext4 事件 + iostat |
| ANR | 缺页中断 / major-fault storm | 锁竞争 + 缓存 miss | am_anr + sched_blocked_reason |
| 系统 CPU 异常高 | TLB shootdown + cache coherency | IRQ 处理 | irq_handler_entry + cpu_idle |
1.4 判断规则
- 规则一(时域规则):如果帧率抖动与 CPU 频率尖峰同步出现,且频率尖峰前存在一段
cpuidle活跃片段,优先怀疑 CPU cache miss。 - 规则二(频域规则):如果 ANR 发生前 2 秒内
pagefault事件数量 > 1000 且major_fault占比 > 30%,缓存命中率极低是直接原因。 - 规则三(对比规则):在相同场景下,对比打开/关闭 HWUI 硬件加速的帧率曲线,若关闭后抖动消失,通常指向 GPU cache miss。
- 规则四(阈值规则):Perfetto 中
cache-references/cache-misses比值 < 0.9 即进入危险区;< 0.7 时几乎必然出现用户可感知卡顿。
1.5 快速自检清单
在进入下一章的数据采集之前,请对照以下清单确认当前问题是否匹配缓存命中率低特征:
- ✓ 用户反馈包含“滑动卡”、“点不动”、“白屏久”等描述
- ✓ 系统日志中出现
InputDispatcher: Timed out waiting for focus - ✓ 通过 dumpsys 观察到
pagecache pressure或kswapd0持续激活 - ✓ 在没有高 CPU 负载的应用中,CPU 频率频繁冲到最高档位
- ✓ 复现时设备温度快速上升(伴随 CPU 持续高频率)
排查技巧:如果遇到偶发卡顿,建议先用 adb 持续抓取 30 秒 trace(包含
-a -b 30000 cpu freq 等类别),然后通过“现象 → 时间戳”在 trace 内精确锚定异常窗口。不要仅靠肉眼观察反复复现,那样会浪费大量时间。
adb shell 一键抓取步骤(供本章快速验证使用):
adb shell perfetto -c - -o /data/misc/perfetto-traces/trace.perfetto \
--txt -t 30s <