第4章:Perfetto Trace配置与捕获:Ftrace事件、CPU频率、调度、GPU、Buffer、Power、内存

4.1 现象识别

帧率抖动(jank)在显示端表现为掉帧、卡顿、滑动不平滑,在Perfetto trace中对应以下可观测现象:

  • Vsync周期打乱:相邻帧的发布时间间隔超过16.6ms(60Hz)或11.1ms(90Hz)。
  • SurfaceFlinger主线程超时:dequeueBuffer / queueBuffer 耗时 > 8ms。
  • CPU/GPU频率长时间低位:intent触发时未及时抬频。
  • Buffer饥饿:App端 acquireFence 等待时间过长。
  • CPU调度延迟:渲染线程被长时间压制在 little core。
现象Trace中典型信号对应事件组
帧间隔抖动Choreographer::doFrame 间隔不均sched_switch + vsync_event
GPU负载尖刺gpu_frequency 在低/高之间反复跳变power/gpu_frequency
内存压力LMK kills 或 lowmemorykiller 事件oom_score_adj_update / lowmemorykiller
Buffer延迟dequeueBuffer 等待 > 4msftrace/buffer_hit / buffer_miss
观察提示:使用 Perfetto 抓取 3 秒左右短 trace,关注卡顿段前后的调度、频率和 buffer 状态,初步定位抖动类型。

4.2 数据采集 — Perfetto Trace 配置实战

Perfetto 支持通过 命令行工具 或 UI 配置 生成自定义 trace 配置文件(.cfg)。本章聚焦帧率抖动排查专用配置,需同时开启以下关键数据源。

4.2.1 核心 Ftrace 事件选通

# 必须开启的基础调度与频率事件
ftrace_events: "power/cpu_frequency"
ftrace_events: "power/cpu_idle"
ftrace_events: "power/suspend_resume"
ftrace_events: "sched/sched_switch"
ftrace_events: "sched/sched_wakeup"
ftrace_events: "sched/sched_waking"
ftrace_events: "sched/sched_process_exit"
ftrace_events: "task/task_newtask"
ftrace_events: "task/task_rename"

# GPU 频率与 idle
ftrace_events: "power/gpu_frequency"
ftrace_events: "power/gpu_idle"

# Buffer 状态(Android 自定义事件)
ftrace_events: "fence/fence_init"
ftrace_events: "fence/fence_destroy"
ftrace_events: "fence/fence_enable_signal"
ftrace_events: "fence/fence_signaled"
ftrace_events: "gpu_mem/gpu_mem_total"

# 内存压力(lowmemorykiller 需内核支持)
ftrace_events: "lowmemorykiller/lowmemorykiller_dump_task"

4.2.2 CPU、内存与Power 统计

# 定期采集 CPU 总负载与内存占用(非ftrace,使用 data sources)
data_sources: {
    config {
        name: "android.power"
    }
}
data_sources: {
    config {
        name: "android.lmkd"
    }
}
data_sources: {
    config {
        name: "linux.process_stats"
        process_stats_config {
            scan_all_processes_on_start: true
            proc_stats_walk_cache_enabled: true
        }
    }
}
data_sources: {
    config {
        name: "linux.sys_stats"
        sys_stats_config {
            meminfo_period_ms: 1000
            vmstat_period_ms: 1000
        }
    }
}

4.2.3 内存详细快照(Heap Profiler)

当怀疑 native 内存泄漏引起帧率下降时,可附加 heap profiler:

# Heap profiler 配置(仅用于短期定位,避免trace过大)
data_sources: {
    config {
        name: "android.heapprofd"
        heapprofd_config {
            sampling_interval_bytes: 4096
            process_cmdline: "com.example.app"
            adaptive_sampling: true
        }
    }
}

4.2.4 完整配置模板(帧率抖动专用)

# 帧率抖动排查用 Perfetto 配置 v2.0
buffers: {
    size_kb: 65536
    fill_policy: DISCARD
}
buffers: {
    size_kb: 4096
    fill_policy: RING_BUFFER
}
data_sources: {
    config {
        name: "android.perfetto.traced_perf"
        perf_event_config {
            timebase {
                frequency: 100
            }
            callstack_sampling {
                scope: SCOPE_TARGET_PROCESS
                target_pid: 1234
            }
        }
    }
}
# (以上 ftrace_events、data_sources 合并)
duration_ms: 5000
使用命令 adb push perfetto_config.cfg /data/local/tmp 推送,再执行 adb shell perfetto -c /data/local/tmp/perfetto_config.cfg -o /data/misc/perfetto-traces/trace.perfetto-trace 开始捕获。

4.3 原因定位 — trace 关键线索解读

捕获完成后,用 Perfetto UI 打开 trace,按以下表格定位根因区间:

排查表项在UI中检查位置判断规则
CPU频率是否及时抬升选择 “CPU Frequency” track,对比帧间隔帧开始前 1~2ms 频率应升到最高频(如 2.8GHz),否则标注为 频率响应慢
渲染线程运行在哪类 core调度 track,查看 tid 所在 cpu若持续位于 little core(如 cpu0-3)且相邻 core 空闲,则为 调度绑定错误
GPU 频率是否匹配负载“GPU Frequency”+“GPU Completion” track渲染任务提交后 GPU 频率未及时升高 > 30ms,造成后续帧延迟
Buffer dequeue 耗时搜索 “dequeueBuffer” Event单次 dequeue 耗时 > 5ms 且伴随 acquireFence 未信号,则为 buffer 饥饿
Power 状态异常“Power Rail” + “Thermal”频繁进入 suspend/ thermal throttle 导致频率锁定
注意:帧率抖动往往由多个因素叠加引起。建议先提取3~5帧的完整时间线(Vsync → App Draw → GPU Render → HWC Compose),逐个环节打标再汇总根因。

4.4 修复动作

基于 trace 排查后,常见修复方向:

  • 频率响应慢 → 调整 cpufreq governor 为 schedutil 或添加 early_demand 触发。
  • 调度绑定错误 → 使用 cpuset 将渲染线程固定到 big core,或调整 load balancer 门槛。
  • GPU 频率匹配滞后 → 在渲染提交前通过 sysfs 预置 GPU 频率,或调整 devfreq 向上调频时间。
  • buffer 饥饿 → 增加 BufferQueue 深度,或优化 App 端 dequeue 时机(提前 8ms 预分配)。
  • Power 限制 → 与 PMIC 团队协调 thermal 策略,减少 throttling 幅度。

4.5 复测

执行修复后:

  1. 使用同一份 Perfetto 配置再次捕获 5 秒 trace。
  2. 在 Perfetto UI 中标记修复前后的帧区间,对比 帧间隔标准差 和 jank 次数。
  3. 确认所有排查表项中的异常点消失,且修复场景下无新问题。
复测时建议保持同一测试场景(相同 UI 操作、相同屏幕亮度、相同后台进程),避免干扰变量。

4.6 预防

  • 持续集成:将 Perfetto 配置集成到 CI 回归中,每次构建后抓取 2 秒 trace 并自动检测频率/调度异常。
  • 阈值告警:对 gpu_frequency 低值持续时长、dequeueBuffer 耗时 P99 设置监控看板。
  • 文档化:将本章节配置模板作为研发团队标准排查工具,定期更新 Ftrace 事件列表。
建议将 Perfetto 配置文件存放在版本仓库 tools/perfetto/ 目录下,并附带 README 说明每个事件的用途和预期行为。
帧率抖动排查 — Perfetto Trace 配置决策树 帧率抖动上报 识别抖动现象类型 CPU调度&频率 sched_switch + cpu_frequency GPU频率 & 完成时间 gpu_frequency + gpu_idle Buffer 饥饿 fence + dequeueBuffer 选择对应 Perfetto 配置模板 adb 执行捕获 5s trace UI 分析 → 定位根因 复测与预防

图4-1 帧率抖动排查 Perfetto 配置决策树:根据现象选择事件组,执行捕获后定位根因