【Android 性能分析】第五天:Perfetto UI分析CPU

Perfetto UI

Perfetto UI 是基于浏览器的可视化分析工具,核心优势在于能解析并展示系统级的多维度性能数据,包括 CPU 调度、内存分配、功耗状态、应用方法调用等。

与 Android Studio Profiler 侧重应用内数据不同,Perfetto UI 更擅长呈现"应用-系统-硬件"的全链路交互,尤其适合定位跨进程依赖、CPU 调度延迟、大小核负载不均等复杂性能问题。

其核心特点包括:

  1. 多格式兼容:支持解析 Perfetto 原生格式(.perfetto-trace)、旧版 Systrace 格式(.ctrace)等多种 trace 文件;
  2. 交互灵活:提供丰富的缩放、筛选、搜索功能,可精准聚焦感兴趣的时间片段和数据维度;
  3. 扩展能力强:支持通过自定义配置捕获特定数据,还能通过命令行和宏实现分析流程自动化;
  4. 跨平台支持:无需安装客户端,直接通过浏览器访问官网即可使用,适配 Windows、Mac、Linux 等多种系统。

前期准备

要使用 Perfetto UI 进行分析,首先需要生成包含目标性能数据的 trace 文件。

Perfetto 支持两种主流的 trace 生成方式,可根据需求灵活选择。

方式 1:通过 Android Studio Profiler 导出(新手友好)

如果习惯使用 Android Studio 的可视化操作,可直接通过 Profiler 生成并导出 trace 文件,步骤如下:

  1. 打开 Android Studio,连接测试设备并启动待分析应用,确保设备处于调试模式;
  2. 打开 Profiler 工具窗口(View > Tool Windows > Profiler),在左侧进程列表中选择目标应用进程;
  3. 点击 Profiler 界面中的「Capture System Activities」按钮(系统跟踪),在弹出的配置窗口中,默认已勾选 CPU、线程调度等核心选项,可根据分析需求补充勾选其他模块(如内存、功耗);
  4. 点击「Record」开始录制,同时在设备上执行待测试操作(如触发应用卡顿、启动流程),完成后点击「Stop」结束录制;
  5. 录制完成后,点击 Profiler 右上角的「Export」按钮,选择导出格式为「Perfetto (.perfetto-trace)」,保存到本地指定路径。
方式 2:通过命令行录制(灵活可控,适合深度分析)

对于需要自定义捕获范围(如特定 CPU 事件、采样频率)的场景,命令行录制是更优选择。前提是确保设备已连接电脑,且 adb 环境配置正常,具体步骤如下:

  1. 终端执行 adb devices 验证设备连接状态,确保设备正常识别;

  2. 编写录制配置(核心是指定需要捕获的数据来源),以下是针对 CPU 分析的基础配置示例(可直接在终端输入):

    bash 复制代码
    # 录制 10 秒 CPU 相关数据,保存到设备本地,后拉取到电脑
    adb shell perfetto \
      -o /data/misc/perfetto-traces/cpu_analysis.perfetto-trace \
      --config - <<EOF
    buffers: {
      size_kb: 65536  # 缓冲区大小,越大越不易丢失数据
      fill_policy: RING_BUFFER  # 环形缓冲区,满后覆盖旧数据
    }
    data_sources: {
      # 捕获进程/线程基础信息
      config {
        name: "linux.process_stats"
        target_buffer: 0
      }
    }
    data_sources: {
      # 捕获 CPU 调度、频率变化等核心事件
      config {
        name: "linux.ftrace"
        target_buffer: 0
        ftrace_config {
          ftrace_events: "sched/sched_switch"  # 线程切换事件
          ftrace_events: "          ftrace_events: "sched/sched_wakeup"  # 线程唤醒事件
          ftrace_events: "cpu_freq/cpu_frequency"  # CPU 频率变化
          ftrace_events: "cpu_idle/cpu_idle"  # CPU 空闲状态
          atrace_categories: "sched"  # 调度相关分类
          atrace_categories: "app"  # 应用相关事件
        }
      }
    }
    duration_ms: 10000  # 录制时长 10 秒
    EOF
  3. 录制完成后,执行以下命令将设备上的 trace 文件拉取到电脑本地:

    bash 复制代码
    adb pull /data/misc/perfetto-traces/cpu_analysis.perfetto-trace ./

核心操作

1. 导入 trace 文件
  1. 打开浏览器,访问 Perfetto UI 官方地址:https://ui.perfetto.dev/
  2. 导入文件的三种方式:点击界面中央的「Open trace file」选择本地文件、直接将 trace 文件拖放到界面中央,或点击左侧「Example traces」选择官方示例文件练习;
  3. 等待文件加载完成(加载时间取决于文件大小,大文件可能需要数秒),加载成功后将进入主分析界面。
2. 主界面核心区域解析

加载完成后,界面主要分为 4 个核心区域,各区域功能如下:

  • 时间轴区域(中央主体):展示从录制开始到结束的完整时间线,包含 CPU 核心状态、进程/线程活动、事件标记等多个"轨道"(Track),不同颜色代表不同状态(如绿色代表 Running、蓝色代表 Sleeping);
  • 左侧 Tracks 面板:列出当前 trace 文件中的所有可查看轨道,包括 CPU 核心轨道(CPU 0-CPU N)、进程轨道(按包名区分)、线程轨道(隶属于对应进程)等,可通过勾选/取消勾选控制轨道显示/隐藏;
  • 右侧详情面板:选中时间轴上的任意事件后,此处将显示该事件的详细信息,如事件开始/结束时间、耗时、涉及的进程/线程 ID、参数等;
  • 顶部工具栏:包含搜索框、缩放按钮、时间范围选择器等,支持快速定位关键词和调整时间视图范围。
3. 基础交互技巧(高效分析的关键)

Perfetto UI 的交互逻辑贴合"精准聚焦"需求,掌握以下快捷键和操作方式能大幅提升分析效率:

  • 缩放与平移:使用鼠标滚轮可直接缩放时间轴;按住 Shift 键 + 鼠标拖拽可平移时间范围;也可使用 WASD 键(W 放大、S 缩小、A 左移、D 右移);
  • 事件选择:点击时间轴上的任意事件块(如线程的 Running 片段、调度事件标记),即可选中并在右侧查看详情;使用「.」和「,」键可快速切换同一轨道上的相邻事件;
  • 区域选择:点击并拖拽时间轴可选中某一时间段,生成区域选择,便于分析特定时间片段内的所有事件;按「R」键可将当前选中的单个事件转换为区域选择;
  • 快速搜索:按「Ctrl + P」(Mac 为「Cmd + P」)打开轨道搜索框,输入进程名、线程名或轨道关键词,可快速定位目标轨道;顶部搜索框输入事件名、参数等,可全局筛选事件;
  • 轨道管理:点击轨道名称旁的「Pin」图标可将轨道固定到顶部,避免滚动时丢失;按「Q」键可快速显示/隐藏右侧详情面板;
  • 命令面板:按「Ctrl + Shift + P」(Mac 为「Cmd + Shift + P」)打开命令面板,可通过输入命令快速执行常见操作(如固定 CPU 轨道、导出数据等),命令支持模糊匹配。

核心分析场景

Perfetto UI 的核心价值在于通过多维度数据关联分析定位问题,以下是针对 CPU 性能分析的核心场景,覆盖从宏观负载到微观方法耗时的全链路分析流程。

场景 1:CPU 核心负载与频率分析

该场景用于判断 CPU 整体负载是否均衡、大小核调度是否合理,是定位"卡顿但应用 CPU 占比不高"等问题的关键步骤:

  1. 在左侧 Tracks 面板中,勾选所有「CPU X」轨道(X 为核心编号,如 CPU 0、CPU 1),时间轴将显示各核心的使用率变化;
  2. 核心轨道中,红色占比越高表示使用率越高,可直观观察是否存在某核心长期 100% 占用(过载)或某核心长期空闲(负载不均)的情况;
  3. 若需查看 CPU 频率变化,确保录制时已开启「cpu_freq/cpu_frequency」事件,在时间轴中找到「cpu_frequency」轨道,可查看各核心频率的动态调整过程(如从 1.2GHz 飙升至 2.4GHz 的时机);
  4. 结合进程轨道分析:将 CPU 核心轨道与目标应用进程轨道对齐,观察应用线程在不同核心上的调度情况,判断是否存在"关键线程被调度到小核导致性能不足"的问题。
场景 2:线程调度与状态分析

线程状态的变化直接反映应用的执行效率,通过该分析可定位线程阻塞、调度延迟等问题:

  1. 在左侧 Tracks 面板中,展开目标应用进程(按包名查找,如 com.example.app),勾选需要分析的线程(如 main 线程、工作线程);
  2. 线程轨道中不同颜色代表不同状态:绿色(Running,正在占用 CPU)、蓝色(Sleeping,休眠)、黄色(Runnable,等待 CPU 调度)、灰色(Uninterruptible Sleep,等待 I/O 等资源);
  3. 关键分析点:
    • 查看 main 线程是否存在长时间黄色(Runnable)状态:若存在,说明线程已就绪但迟迟无法获得 CPU 时间,可能是 CPU 过载或调度优先级问题;
    • 观察线程切换频率:频繁的线程切换(sched_switch 事件)会增加开销,可能导致卡顿;
    • 定位阻塞原因:选中线程的等待状态片段,右侧详情面板会显示等待的资源类型(如锁、信号量),帮助判断线程阻塞的根源。
场景 3:应用方法耗时分析

若需定位应用内具体方法的执行耗时,需确保录制时开启了方法跟踪配置(如 atrace_categories: "app"),分析步骤如下:

  1. 展开目标应用进程的线程轨道,找到「Java Methods」或「Android App」子轨道(仅开启方法跟踪后可见);
  2. 该轨道中会显示具体的方法调用片段,每个片段的长度代表方法执行耗时,点击片段可在右侧详情面板查看方法名、开始/结束时间、耗时等信息;
  3. 结合线程状态分析:若某方法执行片段内出现线程状态切换(如从 Running 变为 Waiting),说明方法执行过程中存在阻塞,需进一步查看阻塞原因;
  4. 对于 Native 层方法耗时,需在录制时配置 Native 采样相关参数,分析时可在「Native Methods」轨道中查看对应的方法调用信息。
场景 4:调度延迟与循环等待分析

针对复杂的卡顿问题(如大小核线程互相等待),需结合调度事件和线程依赖关系分析:

  1. 在顶部搜索框输入「sched_switch」或「sched_wakeup」,筛选出线程调度相关事件;
  2. 选中某一 sched_switch 事件,右侧详情面板会显示「prev_comm」(上一个运行的线程)和「next_comm」(下一个运行的线程),以及切换的时间点;
  3. 关联多个线程的调度事件:若发现线程 A 等待线程 B 完成,而线程 B 又等待线程 A 释放资源,说明存在循环等待(死锁/活锁),需结合代码层面的同步操作(如 lock、join)进一步定位;
  4. 结合 CPU 核心轨道:观察等待线程是否被调度到性能较低的小核,而被等待线程长期占用大核,这种情况可通过调整线程优先级或亲和性优化。

进阶技巧

1. 自定义录制配置

根据具体分析需求调整录制配置,可减少无关数据干扰,提升 trace 文件的可读性。例如:

  • 若仅关注应用启动性能,可将录制时长设置为启动流程的预估时间(如 20 秒),并增加缓冲区大小(避免数据丢失);
  • 若需分析 Native 层性能,在 data_sources 中添加「linux.perf」配置,开启 Native 采样。
2. 利用启动命令与宏自动化分析

对于重复的分析流程(如每次打开 trace 都需要固定 CPU 轨道),可通过启动命令或宏实现自动化:

  1. 启动命令:进入 Perfetto UI 设置(Settings)>「Startup Commands」,输入 JSON 格式的命令(如固定所有 CPU 轨道),每次打开 trace 时将自动执行;
  2. 宏:在设置>「Macros」中配置命名的命令序列(如"CPU 分析流程"包含固定轨道、筛选调度事件等步骤),后续通过命令面板输入宏名称即可快速执行。
3. 导出分析结果

若需分享分析结论或进一步加工数据,可通过以下方式导出:

  • 选中目标区域或事件,在右侧详情面板点击「Export」导出选中数据;
  • 通过命令面板执行「Export trace」命令,导出完整的 trace 数据或筛选后的子数据。

常见问题与避坑指南

  1. trace 文件无法加载:检查文件格式是否正确(优先使用 .perfetto-trace 格式),若为旧版 Systrace 文件,可尝试转换为 Perfetto 格式后再导入;
  2. 数据缺失(如无 CPU 频率信息):确认录制配置中已勾选对应的事件(如 cpu_freq/cpu_frequency),且设备支持该事件捕获(部分 Intel 平台可能不支持频率事件);
  3. 分析效率低:优先使用搜索和筛选功能定位目标数据,避免盲目浏览全时间轴;常用轨道可固定到顶部,减少重复查找;
  4. 无法查看方法耗时:确保录制时开启了「app」分类的 atrace 事件,且应用为 Debug 模式,若为 Release 模式,方法名可能被混淆,需配置符号表。

总结

Perfetto UI 并非简单的"数据查看工具",而是一套完整的"系统级性能诊断体系"。其核心价值在于能打破应用与系统的边界,呈现全链路的性能数据关联,尤其适合解决以下复杂问题:

  • 应用卡顿但应用内 CPU 占比正常(可能是系统调度或跨进程依赖问题);
  • 大小核负载不均、线程调度延迟导致的性能波动;
  • 跨进程通信、系统服务调用引发的性能瓶颈;
  • Native 层或内核态的性能问题。
相关推荐
阿巴斯甜1 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker2 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95273 小时前
Andorid Google 登录接入文档
android
黄林晴4 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab16 小时前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿19 小时前
Android MediaPlayer 笔记
android
Jony_20 小时前
Android 启动优化方案
android
阿巴斯甜20 小时前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇20 小时前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android