Files
mkdocs/docs/学习笔记/perfetto的使用技巧.md
2026-02-11 00:40:25 +08:00

21 KiB
Raw Permalink Blame History

Perfetto使用技巧

一、Perfetto简介

1. 什么是Perfetto

Perfetto是Google开发的下一代系统级性能分析工具从Android 9API 28开始集成到系统中。它是Systrace的升级版提供了更强大的功能和更好的性能。

2. Perfetto的优势

  • 更长的追踪时间:支持数小时的长时间追踪
  • 更丰富的数据源支持CPU、内存、网络、电源等多种数据源
  • 更强大的分析能力支持SQL查询、自定义分析
  • 更好的可视化Web UI界面更友好交互更流畅
  • 更灵活的配置:支持配置文件,可以精确控制追踪内容

3. 适用场景

  • 应用启动性能分析
  • 游戏帧率问题分析
  • 系统卡顿问题定位
  • 内存泄漏排查
  • CPU性能分析
  • 网络性能分析
  • 电源管理分析

二、环境准备与安装

1. 系统要求

  • Android版本Android 9API 28及以上
  • 设备要求需要root权限或userdebug版本
  • 开发环境ADB工具、Python 3.6+(可选)

2. 检查设备支持

# 检查Perfetto是否可用
adb shell perfetto --help

# 检查设备Android版本
adb shell getprop ro.build.version.release

# 检查设备是否支持Perfetto
adb shell getprop ro.build.version.sdk

3. 获取Perfetto工具

3.1 通过Android Studio

Android Studio内置了Perfetto支持可以直接使用Profiler功能。

3.2 通过命令行

Perfetto已经集成在Android系统中可以直接通过adb使用。

3.3 通过Web UI

访问 https://ui.perfetto.dev/ 可以在线分析Trace文件。

4. 安装Python依赖可选

如果需要使用Python脚本处理Trace文件

# 安装protobuf
pip install protobuf

# 安装perfetto Python库
pip install perfetto

三、基础使用

1. 快速开始

1.1 最简单的录制

# 录制10秒的Trace
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t 10s

# 拉取Trace文件
adb pull /data/misc/perfetto-traces/trace trace.pb

# 在Web UI中打开
# 访问 https://ui.perfetto.dev/ 并上传trace.pb

1.2 指定应用录制

# 录制指定应用的Trace
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace \
    -a com.example.app -t 10s

2. 命令行参数

2.1 常用参数

# -c: 配置文件(- 表示使用默认配置)
adb shell perfetto -c -

# --out: 输出文件路径
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace

# -t: 录制时长
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t 10s
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t 5m
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t 1h

# -a: 指定应用包名
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -a com.example.app

# --txt: 使用文本格式配置文件
adb shell perfetto -c /data/local/tmp/config.txt --out /data/local/tmp/trace.pb

2.2 高级参数

# --background: 后台运行
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace --background

# --detach: 分离模式(录制完成后自动停止)
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace --detach

# --stop: 停止正在运行的录制
adb shell perfetto --stop

3. 配置文件使用

3.1 配置文件格式

Perfetto支持两种配置文件格式

  • 文本格式(.txt:人类可读,易于编辑
  • 二进制格式(.pb:更紧凑,性能更好

3.2 基础配置文件

基础配置basic_config.txt

buffers: {
    size_kb: 63488
    fill_policy: DISCARD
}

data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            ftrace_events: "sched/sched_switch"
            ftrace_events: "sched/sched_waking"
            atrace_categories: "gfx"
            atrace_categories: "view"
            buffer_size_kb: 2048
        }
    }
}

duration_ms: 10000

3.3 使用配置文件

# 1. 创建配置文件
cat > config.txt << 'EOF'
buffers: {
    size_kb: 63488
}
data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            atrace_categories: "gfx"
            atrace_categories: "view"
        }
    }
}
duration_ms: 10000
EOF

# 2. 推送到设备
adb push config.txt /data/local/tmp/

# 3. 使用配置文件录制
adb shell perfetto -c /data/local/tmp/config.txt --out /data/local/tmp/trace.pb

# 4. 拉取Trace文件
adb pull /data/local/tmp/trace.pb trace.pb

四、常用配置模板

1. 启动性能分析配置

startup_config.txt

buffers: {
    size_kb: 63488
    fill_policy: DISCARD
}

data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            # CPU调度事件
            ftrace_events: "sched/sched_switch"
            ftrace_events: "sched/sched_waking"
            ftrace_events: "sched/sched_process_exit"
            ftrace_events: "sched/sched_process_free"
            ftrace_events: "task/task_newtask"
            ftrace_events: "task/task_rename"
            
            # 电源管理事件
            ftrace_events: "power/cpu_frequency"
            ftrace_events: "power/cpu_idle"
            ftrace_events: "power/suspend_resume"
            
            # ATrace类别
            atrace_categories: "am"           # Activity Manager
            atrace_categories: "wm"          # Window Manager
            atrace_categories: "gfx"          # Graphics
            atrace_categories: "view"         # View System
            atrace_categories: "binder_driver" # Binder Driver
            atrace_categories: "binder_lock"   # Binder Lock
            atrace_categories: "input"         # Input
            atrace_categories: "res"           # Resources
            atrace_categories: "dalvik"        # Dalvik VM
            
            buffer_size_kb: 4096
            drain_period_ms: 250
        }
    }
}

data_sources: {
    config {
        name: "android.surfaceflinger.frame"
    }
}

duration_ms: 10000

2. 游戏帧率分析配置

jank_config.txt

buffers: {
    size_kb: 63488
    fill_policy: DISCARD
}

data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            # CPU调度
            ftrace_events: "sched/sched_switch"
            ftrace_events: "sched/sched_waking"
            
            # 电源管理
            ftrace_events: "power/cpu_frequency"
            ftrace_events: "power/cpu_idle"
            
            # GPU事件(根据GPU型号选择
            ftrace_events: "gfx/mali_gpu_total"
            ftrace_events: "gpu_mem_total/gpu_mem_total"
            
            # ATrace类别
            atrace_categories: "gfx"
            atrace_categories: "view"
            atrace_categories: "sched"
            atrace_categories: "freq"
            atrace_categories: "idle"
            
            buffer_size_kb: 8192
            drain_period_ms: 250
        }
    }
}

data_sources: {
    config {
        name: "android.surfaceflinger.frame"
    }
}

duration_ms: 30000

3. 内存分析配置

memory_config.txt

buffers: {
    size_kb: 63488
    fill_policy: DISCARD
}

data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            ftrace_events: "kmem/kmalloc"
            ftrace_events: "kmem/kfree"
            ftrace_events: "kmem/kmem_cache_alloc"
            ftrace_events: "kmem/kmem_cache_free"
            atrace_categories: "dalvik"
            atrace_categories: "gfx"
            buffer_size_kb: 4096
        }
    }
}

data_sources: {
    config {
        name: "android.java_hprof"
        target_buffer: 0
    }
}

duration_ms: 60000

4. 网络分析配置

network_config.txt

buffers: {
    size_kb: 63488
    fill_policy: DISCARD
}

data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            ftrace_events: "net/net_dev_xmit"
            ftrace_events: "net/net_dev_recv"
            atrace_categories: "network"
            buffer_size_kb: 2048
        }
    }
}

data_sources: {
    config {
        name: "linux.network_packets"
    }
}

duration_ms: 30000

5. 全系统分析配置

full_system_config.txt

buffers: {
    size_kb: 63488
    fill_policy: DISCARD
}

data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            # 所有常用事件
            ftrace_events: "sched/sched_switch"
            ftrace_events: "sched/sched_waking"
            ftrace_events: "power/cpu_frequency"
            ftrace_events: "power/cpu_idle"
            ftrace_events: "power/suspend_resume"
            
            # 所有ATrace类别
            atrace_categories: "am"
            atrace_categories: "wm"
            atrace_categories: "gfx"
            atrace_categories: "view"
            atrace_categories: "input"
            atrace_categories: "res"
            atrace_categories: "dalvik"
            atrace_categories: "binder_driver"
            atrace_categories: "binder_lock"
            atrace_categories: "sched"
            atrace_categories: "freq"
            atrace_categories: "idle"
            atrace_categories: "disk"
            atrace_categories: "load"
            atrace_categories: "sync"
            atrace_categories: "workq"
            atrace_categories: "memreclaim"
            atrace_categories: "regulators"
            atrace_categories: "binder_driver"
            atrace_categories: "binder_lock"
            
            buffer_size_kb: 8192
            drain_period_ms: 250
        }
    }
}

data_sources: {
    config {
        name: "android.surfaceflinger.frame"
    }
}

duration_ms: 60000

五、ATrace类别详解

1. 常用类别

类别 说明 使用场景
gfx 图形渲染 帧率分析、渲染性能
view 视图系统 UI性能、布局分析
am Activity Manager 应用启动、Activity生命周期
wm Window Manager 窗口管理、多窗口
input 输入事件 触摸响应、输入延迟
sched CPU调度 CPU性能、任务调度
freq CPU频率 频率管理、性能调频
idle CPU空闲 电源管理、CPU使用率
binder_driver Binder驱动 跨进程通信
binder_lock Binder锁 锁竞争分析
res 资源管理 资源加载、资源管理
dalvik Dalvik VM Java代码执行、GC
disk 磁盘I/O 文件读写、数据库操作
load 系统负载 系统负载分析
sync 同步操作 同步原语、锁
workq 工作队列 后台任务
memreclaim 内存回收 内存管理、GC
network 网络 网络性能分析

2. 类别组合建议

启动分析:

am wm gfx view binder_driver binder_lock input res dalvik

帧率分析:

gfx view sched freq idle

内存分析:

dalvik gfx memreclaim

网络分析:

network disk

全系统分析:

am wm gfx view input res dalvik binder_driver binder_lock sched freq idle disk load sync workq memreclaim

六、高级功能

1. 自定义Trace标记

1.1 Java/Kotlin代码

import android.os.Trace;

public class MyClass {
    public void doSomething() {
        // 开始标记
        Trace.beginSection("my_custom_section");
        
        try {
            // 执行代码
            performOperation();
        } finally {
            // 结束标记必须在finally中调用
            Trace.endSection();
        }
    }
    
    private void performOperation() {
        Trace.beginSection("perform_operation");
        // 操作代码
        Trace.endSection();
    }
}

1.2 C++代码

#include <utils/Trace.h>

void doSomething() {
    // 开始标记
    ATRACE_BEGIN("my_custom_section");
    
    // 执行代码
    performOperation();
    
    // 结束标记
    ATRACE_END();
}

void performOperation() {
    ATRACE_BEGIN("perform_operation");
    // 操作代码
    ATRACE_END();
}

1.3 异步操作标记

import android.os.Trace;

public class AsyncTask {
    public void asyncOperation() {
        Trace.beginAsyncSection("async_operation", 0);
        
        // 启动异步操作
        new Thread(() -> {
            try {
                // 异步操作代码
                performAsyncWork();
            } finally {
                // 结束异步标记
                Trace.endAsyncSection("async_operation", 0);
            }
        }).start();
    }
}

2. 长时间追踪

2.1 录制长时间Trace

# 录制5分钟
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t 5m

# 录制1小时
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t 1h

# 使用配置文件指定时长
# 在配置文件中设置 duration_ms: 3600000  # 1小时

2.2 后台录制

# 后台录制
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace \
    --background -t 10m

# 检查录制状态
adb shell ps | grep perfetto

# 停止录制
adb shell perfetto --stop

3. 多进程追踪

3.1 指定多个应用

# 追踪多个应用
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace \
    -a com.example.app1 -a com.example.app2 -t 10s

3.2 追踪系统进程

# 追踪系统进程需要root
adb root
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace \
    -t 10s

4. 条件追踪

4.1 基于触发器的追踪

# 在配置文件中添加触发器
data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            atrace_categories: "gfx"
            # 触发器:当特定事件发生时开始追踪
            trigger_config {
                trigger_mode: START_TRACING
                trigger_name: "my_trigger"
            }
        }
    }
}

七、Trace文件分析

1. Web UI使用技巧

1.1 基本操作

  • 缩放鼠标滚轮或Ctrl+滚轮
  • 平移:鼠标拖拽或方向键
  • 选择:鼠标点击选择事件
  • 搜索Ctrl+F 或点击搜索框
  • 书签按M键标记当前位置
  • 时间选择Shift+鼠标拖拽选择时间范围

1.2 视图操作

  • 展开/折叠:点击进程/线程名称
  • 高亮:双击事件高亮显示
  • 筛选:使用筛选器过滤事件
  • 排序:点击列标题排序

1.3 快捷键

  • W / S:放大/缩小
  • A / D:左移/右移
  • M:添加书签
  • G:跳转到书签
  • F:查找
  • ?:显示所有快捷键

2. SQL查询

2.1 基础查询

查询所有帧信息:

SELECT * FROM slice WHERE name = 'Choreographer#doFrame';

查询掉帧:

SELECT 
    ts,
    dur / 1000000.0 AS duration_ms
FROM slice 
WHERE name = 'Choreographer#doFrame' 
AND dur > 16666667
ORDER BY ts;

查询CPU使用率

SELECT 
    cpu,
    COUNT(*) * 100.0 / (SELECT COUNT(*) FROM sched WHERE cpu = s.cpu) AS usage_percent
FROM sched s
GROUP BY cpu;

2.2 高级查询

查询启动时间:

SELECT 
    (SELECT ts FROM slice WHERE name LIKE '%Choreographer#doFrame%' LIMIT 1) - 
    (SELECT ts FROM slice WHERE name LIKE '%startProcess%' LIMIT 1) 
    AS startup_time_ns;

查询主线程阻塞时间:

SELECT 
    SUM(dur) / 1000000.0 AS total_sleep_ms
FROM sched 
WHERE utid = (SELECT utid FROM thread WHERE name LIKE '%main%' LIMIT 1)
AND state = 'S';

查询GC频率

SELECT 
    COUNT(*) AS gc_count,
    (MAX(ts) - MIN(ts)) / 1000000000.0 AS duration_sec,
    COUNT(*) * 1.0 / ((MAX(ts) - MIN(ts)) / 1000000000.0) AS gc_per_sec
FROM slice 
WHERE name LIKE '%GC%';

3. 性能指标分析

3.1 帧率分析

查看帧率:

1. 在顶部选择 "Frame Timeline"
2. 查看每一帧的状态
3. 统计正常帧、掉帧数量
4. 计算平均帧率

使用SQL计算帧率

SELECT 
    COUNT(*) * 1000000000.0 / (MAX(ts) - MIN(ts)) AS fps
FROM slice 
WHERE name = 'Choreographer#doFrame';

3.2 CPU性能分析

查看CPU频率

1. 在顶部选择 "CPU frequency"
2. 查看各核心频率变化
3. 检查是否有降频

查看CPU使用率

1. 在顶部选择 "CPU usage"
2. 查看各核心使用情况
3. 检查是否有瓶颈

3.3 内存分析

查看内存使用:

1. 在顶部选择 "Memory"
2. 查看内存使用趋势
3. 检查是否有内存泄漏

查看GC活动

1. 在主线程中查找 "HeapTaskDaemon"
2. 查看GC频率和耗时
3. 分析GC对性能的影响

八、最佳实践

1. 录制Trace

  1. 明确目标:在录制前明确要分析的问题
  2. 合适时长:选择适当的追踪时间
    • 启动分析5-10秒
    • 帧率分析30-60秒
    • 内存分析1-5分钟
    • 长时间监控:根据需要
  3. 关键类别:只追踪相关的类别,减少文件大小
  4. 多次录制:多次录制确保结果一致
  5. 环境一致:保持测试环境一致
    • 温度
    • 电量
    • 后台应用
    • 网络状态

2. 分析Trace

  1. 系统化分析:按照固定流程分析
  2. 关键指标:关注关键性能指标
  3. 对比分析:与基准版本或竞品对比
  4. 深入分析:找到根本原因
  5. 验证优化:优化后再次录制验证

3. 性能优化

  1. 量化指标:使用具体数值衡量优化效果
  2. 多维度验证:从多个角度验证优化效果
  3. 回归测试:确保优化没有引入新问题
  4. 持续监控:建立性能监控体系

九、常见问题与解决方案

1. 录制问题

问题1权限不足

错误perfetto: permission denied
解决需要root权限或userdebug版本

问题2设备不支持

错误perfetto: command not found
解决检查Android版本需要Android 9+

问题3配置文件格式错误

错误Failed to parse config
解决:检查配置文件格式,使用文本格式更易调试

2. 分析问题

问题1Trace文件过大

解决:
1. 减少追踪时间
2. 减少追踪类别
3. 使用更小的缓冲区
4. 分段录制和分析

问题2找不到关键事件

解决:
1. 确认追踪类别包含相关事件
2. 检查应用是否添加了Trace标记
3. 使用搜索功能查找
4. 查看相关进程和线程

问题3性能数据不准确

解决:
1. 确认追踪配置正确
2. 检查是否有其他进程干扰
3. 多次录制取平均值
4. 对比其他性能工具

3. 性能问题

问题1录制影响性能

解决:
1. 减少追踪类别
2. 使用较小的缓冲区
3. 减少追踪时间
4. 在性能测试时关闭不必要的追踪

问题2Web UI加载慢

解决:
1. 减少Trace文件大小
2. 使用本地Perfetto工具
3. 分段分析Trace文件

十、实用脚本

1. 快速录制脚本

quick_trace.sh

#!/bin/bash

# 快速录制Trace脚本
DURATION=${1:-10}
OUTPUT=${2:-trace.pb}

echo "开始录制 ${DURATION} 秒的Trace..."
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t ${DURATION}s

echo "拉取Trace文件..."
adb pull /data/misc/perfetto-traces/trace ${OUTPUT}

echo "Trace文件已保存为: ${OUTPUT}"
echo "可以在 https://ui.perfetto.dev/ 打开分析"

使用方法:

chmod +x quick_trace.sh
./quick_trace.sh 10 trace.pb

2. 应用启动分析脚本

startup_trace.sh

#!/bin/bash

PACKAGE=${1:-com.example.app}
OUTPUT=${2:-startup_trace.pb}

echo "开始录制 ${PACKAGE} 的启动Trace..."
adb shell perfetto -c - --out /data/misc/perfetto-traces/trace \
    -a ${PACKAGE} -t 10s

echo "拉取Trace文件..."
adb pull /data/misc/perfetto-traces/trace ${OUTPUT}

echo "启动Trace已保存为: ${OUTPUT}"

使用方法:

chmod +x startup_trace.sh
./startup_trace.sh com.example.app startup.pb

3. 批量分析脚本

batch_analysis.sh

#!/bin/bash

# 批量录制和分析Trace
for i in {1..5}; do
    echo "录制第 ${i} 次Trace..."
    adb shell perfetto -c - --out /data/misc/perfetto-traces/trace_${i} -t 10s
    adb pull /data/misc/perfetto-traces/trace_${i} trace_${i}.pb
    echo "第 ${i} 次Trace已保存"
done

echo "所有Trace录制完成"

十一、进阶技巧

1. 性能基准建立

建立性能基准:

1. 在稳定版本上录制Trace
2. 记录关键性能指标
3. 建立性能基准数据库
4. 定期更新基准

2. 自动化性能测试

集成到CI/CD

1. 在自动化测试中录制Trace
2. 自动分析关键指标
3. 设置性能阈值
4. 性能回归自动告警

3. 性能报告生成

生成性能报告:

1. 使用SQL查询提取数据
2. 使用脚本处理数据
3. 生成可视化报告
4. 定期发送性能报告

十二、参考资料

1. 官方文档

2. 相关工具

  • SystraceAndroid系统追踪工具
  • Android Studio ProfilerIDE集成性能分析工具
  • TraceviewJava代码性能分析工具

3. 学习资源


最后更新2024年