From 9baf22a1ba6d9b909e7be2c6674d6ed1040a9e4c Mon Sep 17 00:00:00 2001 From: renjianbo <18691577328@163.com> Date: Wed, 11 Feb 2026 00:57:50 +0800 Subject: [PATCH] =?UTF-8?q?=E9=8F=87=E5=AD=98=E6=9F=8A=E9=8F=82=E5=9B=A8?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../perfetto分析trace提效的办法或者方案.md | 1040 +++++++++++++++++ docs/学习笔记/perfetto看trace关键词.md | 488 ++++++++ mkdocs.yml | 2 + 3 files changed, 1530 insertions(+) create mode 100644 docs/学习笔记/perfetto分析trace提效的办法或者方案.md create mode 100644 docs/学习笔记/perfetto看trace关键词.md diff --git a/docs/学习笔记/perfetto分析trace提效的办法或者方案.md b/docs/学习笔记/perfetto分析trace提效的办法或者方案.md new file mode 100644 index 0000000..3835dff --- /dev/null +++ b/docs/学习笔记/perfetto分析trace提效的办法或者方案.md @@ -0,0 +1,1040 @@ +# Perfetto分析Trace提效方案 + +## 一、提效概述 + +### 1. 提效目标 + +- **减少分析时间**:从数小时缩短到数十分钟 +- **提高分析准确性**:减少人为错误 +- **标准化流程**:建立可复用的分析流程 +- **自动化分析**:减少重复性工作 +- **知识积累**:建立分析模板和案例库 + +### 2. 提效策略 + +1. **工具自动化**:使用脚本和工具自动化重复操作 +2. **流程标准化**:建立标准化的分析流程 +3. **模板复用**:使用配置模板和分析模板 +4. **批量处理**:批量录制和分析Trace +5. **智能分析**:使用SQL和工具进行智能分析 + +## 二、工具和脚本自动化 + +### 1. 快速录制脚本 + +#### 1.1 通用录制脚本 + +**quick_trace.sh:** +```bash +#!/bin/bash + +# 快速录制Trace脚本 +# 用法: ./quick_trace.sh [时长] [输出文件] [应用包名] + +DURATION=${1:-10} +OUTPUT=${2:-trace.pb} +PACKAGE=${3:-""} + +echo "开始录制 ${DURATION} 秒的Trace..." + +if [ -z "$PACKAGE" ]; then + adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t ${DURATION}s +else + adb shell perfetto -c - --out /data/misc/perfetto-traces/trace \ + -a ${PACKAGE} -t ${DURATION}s +fi + +echo "拉取Trace文件..." +adb pull /data/misc/perfetto-traces/trace ${OUTPUT} + +echo "Trace文件已保存为: ${OUTPUT}" +echo "可以在 https://ui.perfetto.dev/ 打开分析" +``` + +**使用方法:** +```bash +chmod +x quick_trace.sh + +# 录制10秒 +./quick_trace.sh 10 trace.pb + +# 录制指定应用 +./quick_trace.sh 10 startup.pb com.example.app +``` + +#### 1.2 启动分析脚本 + +**startup_trace.sh:** +```bash +#!/bin/bash + +# 应用启动分析脚本 +# 用法: ./startup_trace.sh [应用包名] [输出文件] + +PACKAGE=${1:-com.example.app} +OUTPUT=${2:-startup_trace.pb} + +echo "准备录制 ${PACKAGE} 的启动Trace..." +echo "请在3秒内启动应用..." + +sleep 3 + +echo "开始录制..." +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}" +``` + +#### 1.3 卡顿分析脚本 + +**jank_trace.sh:** +```bash +#!/bin/bash + +# 卡顿分析脚本 +# 用法: ./jank_trace.sh [时长] [输出文件] [应用包名] + +DURATION=${1:-30} +OUTPUT=${2:-jank_trace.pb} +PACKAGE=${3:-""} + +echo "准备录制卡顿Trace..." +echo "请在3秒内复现卡顿问题..." + +sleep 3 + +echo "开始录制 ${DURATION} 秒..." + +if [ -z "$PACKAGE" ]; then + adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t ${DURATION}s +else + adb shell perfetto -c - --out /data/misc/perfetto-traces/trace \ + -a ${PACKAGE} -t ${DURATION}s +fi + +echo "拉取Trace文件..." +adb pull /data/misc/perfetto-traces/trace ${OUTPUT} + +echo "卡顿Trace已保存为: ${OUTPUT}" +``` + +### 2. 批量分析脚本 + +#### 2.1 批量录制脚本 + +**batch_record.sh:** +```bash +#!/bin/bash + +# 批量录制Trace脚本 +# 用法: ./batch_record.sh [次数] [时长] [应用包名] + +COUNT=${1:-5} +DURATION=${2:-10} +PACKAGE=${3:-""} + +echo "批量录制 ${COUNT} 次Trace,每次 ${DURATION} 秒..." + +for i in $(seq 1 $COUNT); do + echo "录制第 ${i} 次Trace..." + + if [ -z "$PACKAGE" ]; then + adb shell perfetto -c - --out /data/misc/perfetto-traces/trace_${i} -t ${DURATION}s + else + adb shell perfetto -c - --out /data/misc/perfetto-traces/trace_${i} \ + -a ${PACKAGE} -t ${DURATION}s + fi + + adb pull /data/misc/perfetto-traces/trace_${i} trace_${i}.pb + echo "第 ${i} 次Trace已保存为 trace_${i}.pb" + + sleep 2 +done + +echo "所有Trace录制完成" +``` + +#### 2.2 批量拉取脚本 + +**batch_pull.sh:** +```bash +#!/bin/bash + +# 批量拉取Trace文件 +# 用法: ./batch_pull.sh [文件数量] + +COUNT=${1:-5} +OUTPUT_DIR=${2:-traces} + +mkdir -p ${OUTPUT_DIR} + +echo "批量拉取 ${COUNT} 个Trace文件..." + +for i in $(seq 1 $COUNT); do + echo "拉取 trace_${i}..." + adb pull /data/misc/perfetto-traces/trace_${i} ${OUTPUT_DIR}/trace_${i}.pb 2>/dev/null +done + +echo "所有Trace文件已保存到 ${OUTPUT_DIR}/" +``` + +### 3. 自动化分析脚本 + +#### 3.1 SQL查询脚本 + +**analyze_trace.py:** +```python +#!/usr/bin/env python3 +""" +Perfetto Trace自动化分析脚本 +用法: python analyze_trace.py trace.pb +""" + +import sys +import subprocess +import json + +def run_sql_query(trace_file, sql_query): + """执行SQL查询""" + # 使用perfetto命令行工具执行SQL查询 + # 注意:这需要perfetto命令行工具支持SQL查询 + cmd = ['perfetto', '--query', sql_query, trace_file] + result = subprocess.run(cmd, capture_output=True, text=True) + return result.stdout + +def analyze_startup(trace_file): + """分析启动性能""" + queries = { + 'process_creation': """ + SELECT ts, dur / 1000000.0 AS duration_ms + FROM slice + WHERE name LIKE '%startProcess%' + LIMIT 1 + """, + 'application_init': """ + SELECT ts, dur / 1000000.0 AS duration_ms + FROM slice + WHERE name LIKE '%handleBindApplication%' + LIMIT 1 + """, + 'activity_creation': """ + SELECT ts, dur / 1000000.0 AS duration_ms + FROM slice + WHERE name LIKE '%performLaunchActivity%' + LIMIT 1 + """, + 'first_frame': """ + SELECT ts, dur / 1000000.0 AS duration_ms + FROM slice + WHERE name = 'Choreographer#doFrame' + ORDER BY ts + LIMIT 1 + """ + } + + results = {} + for key, query in queries.items(): + output = run_sql_query(trace_file, query) + results[key] = output + + return results + +def analyze_jank(trace_file): + """分析卡顿""" + query = """ + SELECT + COUNT(*) AS jank_count, + AVG(dur) / 1000000.0 AS avg_duration_ms, + MAX(dur) / 1000000.0 AS max_duration_ms + FROM slice + WHERE name = 'Choreographer#doFrame' + AND dur > 16666667 + """ + + return run_sql_query(trace_file, query) + +def analyze_fps(trace_file): + """分析帧率""" + query = """ + SELECT + COUNT(*) * 1000000000.0 / (MAX(ts) - MIN(ts)) AS fps + FROM slice + WHERE name = 'Choreographer#doFrame' + """ + + return run_sql_query(trace_file, query) + +if __name__ == '__main__': + if len(sys.argv) < 2: + print("用法: python analyze_trace.py trace.pb") + sys.exit(1) + + trace_file = sys.argv[1] + + print("分析启动性能...") + startup_results = analyze_startup(trace_file) + print(json.dumps(startup_results, indent=2)) + + print("\n分析卡顿...") + jank_results = analyze_jank(trace_file) + print(jank_results) + + print("\n分析帧率...") + fps_results = analyze_fps(trace_file) + print(fps_results) +``` + +#### 3.2 报告生成脚本 + +**generate_report.py:** +```python +#!/usr/bin/env python3 +""" +生成性能分析报告 +用法: python generate_report.py trace.pb report.html +""" + +import sys +import json +from datetime import datetime + +def generate_html_report(trace_file, output_file): + """生成HTML报告""" + html_template = """ + + + + Perfetto Trace分析报告 + + + +

Perfetto Trace分析报告

+

生成时间: {timestamp}

+

Trace文件: {trace_file}

+ +

性能指标

+
+

启动性能

+

进程创建: {process_creation} ms

+

Application初始化: {app_init} ms

+

Activity创建: {activity_creation} ms

+

首帧渲染: {first_frame} ms

+
+ +
+

帧率

+

平均帧率: {fps} FPS

+

掉帧次数: {jank_count}

+

平均掉帧时长: {avg_jank_duration} ms

+
+ +

分析建议

+ + + + """ + + # 这里应该调用实际的SQL查询获取数据 + # 为了示例,使用占位符 + report = html_template.format( + timestamp=datetime.now().strftime("%Y-%m-%d %H:%M:%S"), + trace_file=trace_file, + process_creation="N/A", + app_init="N/A", + activity_creation="N/A", + first_frame="N/A", + fps="N/A", + jank_count="N/A", + avg_jank_duration="N/A" + ) + + with open(output_file, 'w', encoding='utf-8') as f: + f.write(report) + + print(f"报告已生成: {output_file}") + +if __name__ == '__main__': + if len(sys.argv) < 3: + print("用法: python generate_report.py trace.pb report.html") + sys.exit(1) + + trace_file = sys.argv[1] + output_file = sys.argv[2] + + generate_html_report(trace_file, output_file) +``` + +## 三、配置模板复用 + +### 1. 配置文件模板库 + +#### 1.1 启动分析配置模板 + +**templates/startup_config.txt:** +```protobuf +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: "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_categories: "am" + atrace_categories: "wm" + atrace_categories: "gfx" + atrace_categories: "view" + atrace_categories: "binder_driver" + atrace_categories: "binder_lock" + atrace_categories: "input" + atrace_categories: "res" + atrace_categories: "dalvik" + buffer_size_kb: 4096 + drain_period_ms: 250 + } + } +} + +data_sources: { + config { + name: "android.surfaceflinger.frame" + } +} + +duration_ms: 10000 +``` + +#### 1.2 卡顿分析配置模板 + +**templates/jank_config.txt:** +```protobuf +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: "gfx/mali_gpu_total" + ftrace_events: "gpu_mem_total/gpu_mem_total" + 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 +``` + +### 2. 模板管理脚本 + +**use_template.sh:** +```bash +#!/bin/bash + +# 使用配置模板 +# 用法: ./use_template.sh [模板名] [输出文件] [时长] + +TEMPLATE=${1:-startup} +OUTPUT=${2:-config.txt} +DURATION=${3:-10000} + +TEMPLATE_DIR="templates" +TEMPLATE_FILE="${TEMPLATE_DIR}/${TEMPLATE}_config.txt" + +if [ ! -f "$TEMPLATE_FILE" ]; then + echo "模板文件不存在: $TEMPLATE_FILE" + exit 1 +fi + +# 复制模板并替换时长 +sed "s/duration_ms: [0-9]*/duration_ms: ${DURATION}/" \ + "$TEMPLATE_FILE" > "$OUTPUT" + +echo "配置已生成: $OUTPUT" +``` + +## 四、工作流程优化 + +### 1. 标准化分析流程 + +#### 1.1 启动分析流程 + +``` +1. 准备阶段 + - 明确分析目标 + - 准备测试环境 + - 选择配置模板 + +2. 录制阶段 + - 使用启动分析脚本 + - 启动应用 + - 等待录制完成 + +3. 分析阶段 + - 打开Trace文件 + - 定位关键节点 + - 分析各阶段耗时 + - 识别性能瓶颈 + +4. 报告阶段 + - 记录分析结果 + - 生成分析报告 + - 提供优化建议 +``` + +#### 1.2 卡顿分析流程 + +``` +1. 准备阶段 + - 明确卡顿场景 + - 准备复现步骤 + - 选择配置模板 + +2. 录制阶段 + - 使用卡顿分析脚本 + - 复现卡顿问题 + - 等待录制完成 + +3. 分析阶段 + - 打开Trace文件 + - 定位卡顿时间点 + - 分析主线程状态 + - 分析渲染线程状态 + - 分析系统资源 + +4. 报告阶段 + - 记录卡顿原因 + - 生成分析报告 + - 提供优化建议 +``` + +### 2. 分析检查清单 + +#### 2.1 启动分析检查清单 + +- [ ] 进程创建时间 +- [ ] Application初始化时间 +- [ ] Activity创建时间 +- [ ] 首帧渲染时间 +- [ ] 主线程阻塞情况 +- [ ] 系统服务调用耗时 +- [ ] CPU使用情况 +- [ ] 内存使用情况 + +#### 2.2 卡顿分析检查清单 + +- [ ] 卡顿时间点定位 +- [ ] 帧率统计 +- [ ] 主线程状态分析 +- [ ] RenderThread状态分析 +- [ ] CPU性能分析 +- [ ] 内存性能分析 +- [ ] GPU性能分析 +- [ ] 根本原因定位 + +## 五、快捷键和技巧 + +### 1. Perfetto Web UI快捷键 + +| 快捷键 | 功能 | +|--------|------| +| `W` | 放大时间轴 | +| `S` | 缩小时间轴 | +| `A` | 向左移动 | +| `D` | 向右移动 | +| `M` | 添加书签 | +| `G` | 跳转到书签 | +| `F` | 查找 | +| `?` | 显示所有快捷键 | +| `Shift + 拖拽` | 选择时间范围 | +| `Ctrl + F` | 搜索框 | + +### 2. 快速定位技巧 + +#### 2.1 使用书签 + +``` +1. 找到关键时间点 +2. 按M键添加书签 +3. 给书签命名(如"启动开始"、"首帧") +4. 使用G键快速跳转 +``` + +#### 2.2 使用时间选择 + +``` +1. Shift + 鼠标拖拽选择时间范围 +2. 只显示选择范围内的事件 +3. 缩小分析范围 +4. 提高分析效率 +``` + +#### 2.3 使用筛选器 + +``` +1. 在进程列表中筛选 +2. 在线程列表中筛选 +3. 使用搜索框筛选事件 +4. 只关注相关进程和线程 +``` + +### 3. SQL查询模板 + +#### 3.1 启动时间查询模板 + +```sql +-- 查询启动各阶段耗时 +SELECT + 'Process Creation' AS stage, + (SELECT ts FROM slice WHERE name LIKE '%startProcess%' LIMIT 1) AS start_ts, + (SELECT ts FROM slice WHERE name LIKE '%handleBindApplication%' LIMIT 1) AS end_ts, + ((SELECT ts FROM slice WHERE name LIKE '%handleBindApplication%' LIMIT 1) - + (SELECT ts FROM slice WHERE name LIKE '%startProcess%' LIMIT 1)) / 1000000.0 AS duration_ms +UNION ALL +SELECT + 'Application Init' AS stage, + (SELECT ts FROM slice WHERE name LIKE '%handleBindApplication%' LIMIT 1) AS start_ts, + (SELECT ts FROM slice WHERE name LIKE '%performLaunchActivity%' LIMIT 1) AS end_ts, + ((SELECT ts FROM slice WHERE name LIKE '%performLaunchActivity%' LIMIT 1) - + (SELECT ts FROM slice WHERE name LIKE '%handleBindApplication%' LIMIT 1)) / 1000000.0 AS duration_ms; +``` + +#### 3.2 卡顿分析查询模板 + +```sql +-- 查询掉帧统计 +SELECT + COUNT(*) AS jank_count, + AVG(dur) / 1000000.0 AS avg_duration_ms, + MAX(dur) / 1000000.0 AS max_duration_ms, + MIN(dur) / 1000000.0 AS min_duration_ms +FROM slice +WHERE name = 'Choreographer#doFrame' +AND dur > 16666667; +``` + +#### 3.3 主线程分析查询模板 + +```sql +-- 查询主线程耗时操作 +SELECT + name, + dur / 1000000.0 AS duration_ms, + ts +FROM slice +WHERE utid = (SELECT utid FROM thread WHERE name LIKE '%main%' LIMIT 1) +ORDER BY dur DESC +LIMIT 20; +``` + +## 六、批量处理方案 + +### 1. 批量录制和分析 + +#### 1.1 批量录制脚本 + +**batch_analysis.sh:** +```bash +#!/bin/bash + +# 批量录制和分析脚本 +# 用法: ./batch_analysis.sh [次数] [时长] [应用包名] + +COUNT=${1:-5} +DURATION=${2:-10} +PACKAGE=${3:-com.example.app} +OUTPUT_DIR="batch_traces_$(date +%Y%m%d_%H%M%S)" + +mkdir -p ${OUTPUT_DIR} + +echo "批量录制和分析 ${COUNT} 次Trace..." + +for i in $(seq 1 $COUNT); do + echo "========== 第 ${i} 次 ==========" + + # 录制 + echo "录制Trace..." + adb shell perfetto -c - --out /data/misc/perfetto-traces/trace_${i} \ + -a ${PACKAGE} -t ${DURATION}s + + # 拉取 + echo "拉取Trace文件..." + adb pull /data/misc/perfetto-traces/trace_${i} \ + ${OUTPUT_DIR}/trace_${i}.pb + + # 分析(使用Python脚本) + echo "分析Trace..." + python analyze_trace.py ${OUTPUT_DIR}/trace_${i}.pb > \ + ${OUTPUT_DIR}/analysis_${i}.txt + + echo "第 ${i} 次完成" + echo "" + + sleep 2 +done + +echo "所有Trace已保存到 ${OUTPUT_DIR}/" +echo "分析结果已保存到 ${OUTPUT_DIR}/analysis_*.txt" +``` + +#### 1.2 批量对比脚本 + +**batch_compare.sh:** +```bash +#!/bin/bash + +# 批量对比脚本 +# 用法: ./batch_compare.sh [基准目录] [对比目录] [输出文件] + +BASELINE_DIR=${1:-baseline_traces} +COMPARE_DIR=${2:-compare_traces} +OUTPUT=${3:-compare_report.txt} + +echo "批量对比分析..." +echo "基准目录: ${BASELINE_DIR}" +echo "对比目录: ${COMPARE_DIR}" +echo "输出文件: ${OUTPUT}" + +# 这里应该实现对比逻辑 +# 对比启动时间、帧率、卡顿等指标 + +echo "对比报告已生成: ${OUTPUT}" +``` + +### 2. 自动化报告生成 + +#### 2.1 报告模板 + +**report_template.html:** +```html + + + + 性能分析报告 + + + +

性能分析报告

+ + + +``` + +#### 2.2 报告生成脚本 + +**generate_batch_report.py:** +```python +#!/usr/bin/env python3 +""" +批量生成分析报告 +""" + +import os +import json +from datetime import datetime + +def generate_batch_report(trace_dir, output_file): + """批量生成报告""" + reports = [] + + for trace_file in os.listdir(trace_dir): + if trace_file.endswith('.pb'): + # 分析每个Trace文件 + # 这里应该调用实际的分析函数 + report = { + 'file': trace_file, + 'timestamp': datetime.now().isoformat(), + 'metrics': {} + } + reports.append(report) + + # 生成汇总报告 + with open(output_file, 'w', encoding='utf-8') as f: + json.dump(reports, f, indent=2) + + print(f"批量报告已生成: {output_file}") + +if __name__ == '__main__': + import sys + trace_dir = sys.argv[1] if len(sys.argv) > 1 else 'traces' + output_file = sys.argv[2] if len(sys.argv) > 2 else 'batch_report.json' + generate_batch_report(trace_dir, output_file) +``` + +## 七、团队协作方案 + +### 1. 共享配置和模板 + +#### 1.1 Git仓库管理 + +``` +perfetto-tools/ +├── templates/ # 配置模板 +│ ├── startup_config.txt +│ ├── jank_config.txt +│ └── memory_config.txt +├── scripts/ # 脚本 +│ ├── quick_trace.sh +│ ├── analyze_trace.py +│ └── generate_report.py +├── sql/ # SQL查询模板 +│ ├── startup_queries.sql +│ ├── jank_queries.sql +│ └── memory_queries.sql +└── docs/ # 文档 + ├── README.md + └── best_practices.md +``` + +#### 1.2 配置版本管理 + +- 使用Git管理配置模板 +- 记录配置变更历史 +- 共享最佳实践配置 +- 建立配置评审机制 + +### 2. 知识库建设 + +#### 2.1 案例库 + +- **成功案例**:记录优化成功的案例 +- **问题案例**:记录常见问题和解决方案 +- **分析模板**:建立标准分析模板 +- **优化建议**:积累优化建议库 + +#### 2.2 文档管理 + +- **分析流程文档**:标准化的分析流程 +- **工具使用文档**:工具和脚本使用说明 +- **最佳实践文档**:总结最佳实践 +- **FAQ文档**:常见问题解答 + +### 3. 协作工具 + +#### 3.1 共享Trace文件 + +- 使用云存储共享Trace文件 +- 建立Trace文件命名规范 +- 记录Trace文件元数据 +- 建立Trace文件索引 + +#### 3.2 协作分析 + +- 使用在线协作工具 +- 共享分析结果 +- 建立分析讨论机制 +- 记录分析决策 + +## 八、智能分析方案 + +### 1. 自动化问题检测 + +#### 1.1 问题检测规则 + +**detect_issues.py:** +```python +#!/usr/bin/env python3 +""" +自动检测性能问题 +""" + +def detect_startup_issues(trace_file): + """检测启动问题""" + issues = [] + + # 检测启动时间过长 + # 检测主线程阻塞 + # 检测系统服务调用耗时 + # ... + + return issues + +def detect_jank_issues(trace_file): + """检测卡顿问题""" + issues = [] + + # 检测掉帧 + # 检测主线程阻塞 + # 检测渲染瓶颈 + # ... + + return issues + +def generate_issue_report(issues, output_file): + """生成问题报告""" + with open(output_file, 'w', encoding='utf-8') as f: + for issue in issues: + f.write(f"{issue['type']}: {issue['description']}\n") + f.write(f" 位置: {issue['location']}\n") + f.write(f" 建议: {issue['suggestion']}\n\n") + + print(f"问题报告已生成: {output_file}") +``` + +#### 1.2 性能基准对比 + +**compare_baseline.py:** +```python +#!/usr/bin/env python3 +""" +与性能基准对比 +""" + +def load_baseline(baseline_file): + """加载性能基准""" + with open(baseline_file, 'r') as f: + return json.load(f) + +def compare_with_baseline(trace_file, baseline): + """与基准对比""" + # 分析Trace文件 + # 与基准对比 + # 生成对比报告 + pass +``` + +### 2. 机器学习辅助分析 + +#### 2.1 异常检测 + +- 使用机器学习检测异常模式 +- 自动识别性能问题 +- 提供问题分类和优先级 + +#### 2.2 预测分析 + +- 预测性能趋势 +- 识别潜在问题 +- 提供预防建议 + +## 九、性能监控集成 + +### 1. CI/CD集成 + +#### 1.1 自动化测试 + +**ci_performance_test.sh:** +```bash +#!/bin/bash + +# CI/CD性能测试脚本 + +echo "开始性能测试..." + +# 录制Trace +adb shell perfetto -c - --out /data/misc/perfetto-traces/trace -t 10s +adb pull /data/misc/perfetto-traces/trace ci_trace.pb + +# 分析Trace +python analyze_trace.py ci_trace.pb > ci_analysis.txt + +# 检查性能指标 +python check_performance.py ci_analysis.txt + +# 如果性能不达标,退出 +if [ $? -ne 0 ]; then + echo "性能测试失败" + exit 1 +fi + +echo "性能测试通过" +``` + +#### 1.2 性能回归检测 + +- 在CI/CD中集成性能测试 +- 自动检测性能回归 +- 生成性能报告 +- 通知相关人员 + +### 2. 持续监控 + +#### 2.1 定期分析 + +- 定期录制和分析Trace +- 建立性能趋势图 +- 识别性能退化 +- 及时发现问题 + +#### 2.2 告警机制 + +- 设置性能阈值 +- 自动触发告警 +- 通知相关人员 +- 记录告警历史 + +## 十、总结 + +### 1. 提效关键点 + +1. **工具自动化**:使用脚本自动化重复操作 +2. **流程标准化**:建立标准化的分析流程 +3. **模板复用**:使用配置和分析模板 +4. **批量处理**:批量录制和分析Trace +5. **智能分析**:使用SQL和工具进行智能分析 +6. **团队协作**:建立共享配置和知识库 +7. **持续监控**:集成到CI/CD和监控系统 + +### 2. 实施建议 + +1. **逐步实施**:从简单的脚本开始,逐步完善 +2. **持续改进**:根据实际使用情况不断优化 +3. **知识积累**:建立案例库和最佳实践 +4. **团队培训**:培训团队成员使用工具和流程 + +### 3. 预期效果 + +- **分析时间**:从数小时缩短到数十分钟 +- **分析准确性**:提高分析准确性 +- **知识积累**:建立可复用的知识库 +- **团队效率**:提高团队整体效率 + +--- + +*最后更新:2024年* diff --git a/docs/学习笔记/perfetto看trace关键词.md b/docs/学习笔记/perfetto看trace关键词.md new file mode 100644 index 0000000..f8ad0c3 --- /dev/null +++ b/docs/学习笔记/perfetto看trace关键词.md @@ -0,0 +1,488 @@ +# Perfetto看Trace关键词 + +## 一、应用启动相关关键词 + +### 1. 进程创建 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `startProcess` | 进程启动 | SystemServer/ActivityManagerService | +| `ActivityManager: startProcess` | ActivityManager启动进程 | SystemServer | +| `Zygote: forkAndSpecialize` | Zygote进程fork | Zygote进程 | +| `Process: start` | 进程启动 | SystemServer | +| `task_newtask` | 新任务创建 | Kernel | +| `task_rename` | 任务重命名 | Kernel | + +### 2. Application初始化 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `handleBindApplication` | 绑定Application | 应用主线程 | +| `ActivityThread: handleBindApplication` | ActivityThread处理绑定 | 应用主线程 | +| `Application.onCreate` | Application初始化 | 应用主线程 | +| `attachBaseContext` | 附加基础上下文 | 应用主线程 | +| `installContentProviders` | 安装ContentProvider | 应用主线程 | + +### 3. Activity创建 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `performLaunchActivity` | 执行启动Activity | 应用主线程 | +| `ActivityThread: performLaunchActivity` | ActivityThread启动Activity | 应用主线程 | +| `Activity.onCreate` | Activity创建 | 应用主线程 | +| `Activity.onStart` | Activity启动 | 应用主线程 | +| `Activity.onResume` | Activity恢复 | 应用主线程 | +| `onWindowFocusChanged` | 窗口焦点变化 | 应用主线程 | + +### 4. 首帧渲染 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `Choreographer#doFrame` | 帧调度 | 应用主线程 | +| `onMessageReceived` | 消息接收 | SurfaceFlinger | +| `SurfaceFlinger: onMessageReceived` | SurfaceFlinger接收消息 | SurfaceFlinger | +| `firstFrame` | 首帧 | SurfaceFlinger | +| `Displayed` | 显示完成 | 应用主线程 | + +## 二、渲染相关关键词 + +### 1. 帧调度 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `Choreographer#doFrame` | 帧调度 | 应用主线程 | +| `doFrame` | 执行帧 | 应用主线程 | +| `doCallbacks` | 执行回调 | 应用主线程 | +| `doAnimationFrame` | 执行动画帧 | 应用主线程 | +| `doTraversal` | 执行遍历 | 应用主线程 | + +### 2. 视图系统 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `performTraversals` | 执行遍历 | 应用主线程 | +| `performMeasure` | 执行测量 | 应用主线程 | +| `performLayout` | 执行布局 | 应用主线程 | +| `performDraw` | 执行绘制 | 应用主线程 | +| `onMeasure` | 测量 | 应用主线程 | +| `onLayout` | 布局 | 应用主线程 | +| `onDraw` | 绘制 | 应用主线程 | +| `invalidate` | 失效 | 应用主线程 | +| `requestLayout` | 请求布局 | 应用主线程 | + +### 3. RenderThread + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `drawFrame` | 绘制帧 | RenderThread | +| `dequeueBuffer` | 获取Buffer | RenderThread | +| `queueBuffer` | 提交Buffer | RenderThread | +| `syncAndDrawFrame` | 同步并绘制帧 | RenderThread | +| `flush` | 刷新 | RenderThread | +| `flushCommands` | 刷新命令 | RenderThread | + +### 4. SurfaceFlinger + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `onMessageReceived` | 接收消息 | SurfaceFlinger | +| `onFrameAvailable` | 帧可用 | SurfaceFlinger | +| `doComposition` | 执行合成 | SurfaceFlinger | +| `doComposeSurfaces` | 合成表面 | SurfaceFlinger | +| `postComposition` | 后合成 | SurfaceFlinger | +| `VSync` | 垂直同步 | SurfaceFlinger | +| `onVSync` | VSync事件 | SurfaceFlinger | + +### 5. GPU相关 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `gpu_mem_total` | GPU内存总量 | Kernel | +| `mali_gpu_total` | Mali GPU总量 | Kernel | +| `gpu_freq` | GPU频率 | Kernel | +| `gpu_utilization` | GPU使用率 | Kernel | + +## 三、系统服务相关关键词 + +### 1. ActivityManager + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `ActivityManager: startActivity` | 启动Activity | SystemServer | +| `ActivityManager: startService` | 启动Service | SystemServer | +| `ActivityManager: bindService` | 绑定Service | SystemServer | +| `ActivityManager: startProcess` | 启动进程 | SystemServer | +| `ActivityManager: finishActivity` | 结束Activity | SystemServer | +| `ActivityManager: pauseActivity` | 暂停Activity | SystemServer | +| `ActivityManager: resumeActivity` | 恢复Activity | SystemServer | + +### 2. WindowManager + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `WindowManager: addWindow` | 添加窗口 | SystemServer | +| `WindowManager: removeWindow` | 移除窗口 | SystemServer | +| `WindowManager: relayoutWindow` | 重新布局窗口 | SystemServer | +| `WindowManager: setAppVisibility` | 设置应用可见性 | SystemServer | +| `WindowManager: setInputMethodWindow` | 设置输入法窗口 | SystemServer | + +### 3. Input系统 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `InputReader` | 输入读取器 | Input进程 | +| `InputDispatcher` | 输入分发器 | Input进程 | +| `dispatchKey` | 分发按键 | Input进程 | +| `dispatchMotion` | 分发触摸 | Input进程 | +| `touch` | 触摸事件 | Input进程 | +| `key` | 按键事件 | Input进程 | + +### 4. Binder通信 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `binder_transaction` | Binder事务 | Kernel | +| `binder_transaction_received` | 接收Binder事务 | Kernel | +| `binder_lock` | Binder锁 | Kernel | +| `binder_unlock` | Binder解锁 | Kernel | +| `binder_wait_for_work` | 等待Binder工作 | Kernel | + +## 四、进程和线程相关关键词 + +### 1. 进程名称 + +| 关键词 | 说明 | +|--------|------| +| `system_server` | 系统服务进程 | +| `surfaceflinger` | SurfaceFlinger进程 | +| `zygote` | Zygote进程 | +| `zygote64` | 64位Zygote进程 | +| `input` | 输入服务进程 | +| `logd` | 日志守护进程 | +| `lmkd` | 低内存杀手进程 | + +### 2. 线程名称 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `main` | 主线程 | 应用进程 | +| `RenderThread` | 渲染线程 | 应用进程 | +| `android.anim.if` | 动画线程 | SystemServer | +| `android.ui` | UI线程 | SystemServer | +| `android.display` | 显示线程 | SystemServer | +| `HeapTaskDaemon` | 堆任务守护线程 | 应用进程 | +| `FinalizerDaemon` | 终结器守护线程 | 应用进程 | +| `ReferenceQueueDaemon` | 引用队列守护线程 | 应用进程 | + +## 五、性能指标相关关键词 + +### 1. CPU相关 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `cpu_frequency` | CPU频率 | Kernel | +| `cpu_idle` | CPU空闲 | Kernel | +| `cpu_freq` | CPU频率 | Kernel | +| `sched_switch` | 任务切换 | Kernel | +| `sched_waking` | 任务唤醒 | Kernel | +| `sched_migrate_task` | 任务迁移 | Kernel | +| `sched_process_exit` | 进程退出 | Kernel | +| `sched_process_free` | 进程释放 | Kernel | + +### 2. 内存相关 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `GC` | 垃圾回收 | 应用进程 | +| `HeapTaskDaemon` | 堆任务守护线程 | 应用进程 | +| `ConcurrentGC` | 并发GC | 应用进程 | +| `Alloc` | 内存分配 | 应用进程 | +| `Free` | 内存释放 | 应用进程 | +| `kmalloc` | 内核内存分配 | Kernel | +| `kfree` | 内核内存释放 | Kernel | +| `kswapd` | 交换守护进程 | Kernel | +| `memreclaim` | 内存回收 | Kernel | + +### 3. I/O相关 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `android_fs_dataread_start` | 数据读取开始 | Kernel | +| `android_fs_dataread_end` | 数据读取结束 | Kernel | +| `android_fs_datawrite_start` | 数据写入开始 | Kernel | +| `android_fs_datawrite_end` | 数据写入结束 | Kernel | +| `block_rq_issue` | 块请求发出 | Kernel | +| `block_rq_complete` | 块请求完成 | Kernel | + +### 4. 网络相关 + +| 关键词 | 说明 | 位置 | +|--------|------|------| +| `net_dev_xmit` | 网络设备发送 | Kernel | +| `net_dev_recv` | 网络设备接收 | Kernel | +| `tcp_send` | TCP发送 | Kernel | +| `tcp_receive` | TCP接收 | Kernel | + +## 六、SQL查询常用关键词 + +### 1. 表名 + +| 表名 | 说明 | +|------|------| +| `slice` | 时间片表,包含所有Trace事件 | +| `sched` | 调度表,包含CPU调度信息 | +| `thread` | 线程表,包含线程信息 | +| `process` | 进程表,包含进程信息 | +| `counter` | 计数器表,包含性能计数器 | +| `track` | 轨道表,包含Trace轨道信息 | + +### 2. 常用字段 + +| 字段 | 说明 | 表 | +|------|------|-----| +| `ts` | 时间戳(纳秒) | slice, sched | +| `dur` | 持续时间(纳秒) | slice | +| `name` | 事件名称 | slice | +| `utid` | 线程ID | slice, sched | +| `upid` | 进程ID | slice, sched | +| `cpu` | CPU核心 | sched | +| `state` | 线程状态 | sched | +| `value` | 计数器值 | counter | + +### 3. 常用查询模式 + +#### 查询掉帧 +```sql +SELECT * FROM slice +WHERE name = 'Choreographer#doFrame' +AND dur > 16666667; +``` + +#### 查询主线程耗时操作 +```sql +SELECT name, dur / 1000000.0 AS duration_ms +FROM slice +WHERE utid = (SELECT utid FROM thread WHERE name LIKE '%main%' LIMIT 1) +ORDER BY dur DESC +LIMIT 20; +``` + +#### 查询CPU使用率 +```sql +SELECT cpu, COUNT(*) AS usage +FROM sched +WHERE ts BETWEEN ? AND ? +GROUP BY cpu; +``` + +## 七、常见问题定位关键词 + +### 1. 卡顿问题 + +| 关键词 | 说明 | 用途 | +|--------|------|------| +| `Choreographer#doFrame` | 帧调度 | 查找掉帧 | +| `performTraversals` | 视图遍历 | 查找布局耗时 | +| `drawFrame` | 绘制帧 | 查找渲染耗时 | +| `dequeueBuffer` | 获取Buffer | 查找Buffer分配问题 | +| `queueBuffer` | 提交Buffer | 查找Buffer提交问题 | + +### 2. 启动问题 + +| 关键词 | 说明 | 用途 | +|--------|------|------| +| `startProcess` | 启动进程 | 查找进程创建耗时 | +| `handleBindApplication` | 绑定Application | 查找Application初始化耗时 | +| `performLaunchActivity` | 启动Activity | 查找Activity创建耗时 | +| `onCreate` | 创建 | 查找创建耗时 | + +### 3. 内存问题 + +| 关键词 | 说明 | 用途 | +|--------|------|------| +| `GC` | 垃圾回收 | 查找GC频率和耗时 | +| `HeapTaskDaemon` | 堆任务守护线程 | 查找GC活动 | +| `Alloc` | 内存分配 | 查找内存分配模式 | +| `kswapd` | 交换守护进程 | 查找内存压力 | + +### 4. CPU问题 + +| 关键词 | 说明 | 用途 | +|--------|------|------| +| `cpu_frequency` | CPU频率 | 查找频率问题 | +| `sched_switch` | 任务切换 | 查找调度问题 | +| `sched_waking` | 任务唤醒 | 查找唤醒延迟 | + +## 八、搜索技巧 + +### 1. 精确搜索 + +- **完整匹配**:直接输入关键词,如 `Choreographer#doFrame` +- **部分匹配**:使用通配符,如 `onCreate` 可以匹配所有onCreate方法 +- **正则表达式**:在搜索框中使用正则,如 `.*onCreate.*` + +### 2. 组合搜索 + +- **多关键词**:使用空格分隔,如 `onCreate Activity` +- **排除关键词**:使用 `-` 排除,如 `onCreate -Application` +- **时间范围**:结合时间选择,缩小搜索范围 + +### 3. 常用搜索模式 + +#### 启动相关 +``` +startProcess +handleBindApplication +performLaunchActivity +onCreate +``` + +#### 渲染相关 +``` +Choreographer#doFrame +performTraversals +drawFrame +dequeueBuffer +queueBuffer +``` + +#### 内存相关 +``` +GC +HeapTaskDaemon +Alloc +kswapd +``` + +#### CPU相关 +``` +cpu_frequency +sched_switch +sched_waking +``` + +## 九、快速定位技巧 + +### 1. 使用书签 + +- **标记关键点**:按 `M` 键标记当前位置 +- **跳转书签**:按 `G` 键跳转到书签 +- **管理书签**:在书签列表中管理 + +### 2. 使用时间选择 + +- **选择时间范围**:`Shift + 鼠标拖拽` +- **缩放时间**:`W` 放大,`S` 缩小 +- **平移时间**:`A` 左移,`D` 右移 + +### 3. 使用筛选器 + +- **进程筛选**:只显示特定进程 +- **线程筛选**:只显示特定线程 +- **事件筛选**:只显示特定事件 + +### 4. 使用SQL查询 + +- **快速统计**:使用SQL查询快速获取统计数据 +- **复杂分析**:使用SQL进行复杂的数据分析 +- **导出数据**:使用SQL查询结果导出数据 + +## 十、关键词速查表 + +### 启动流程关键词 +``` +startProcess → handleBindApplication → performLaunchActivity → +onCreate → onStart → onResume → Choreographer#doFrame +``` + +### 渲染流程关键词 +``` +Choreographer#doFrame → performTraversals → performMeasure → +performLayout → performDraw → drawFrame → dequeueBuffer → +queueBuffer → onMessageReceived +``` + +### 内存回收关键词 +``` +GC → HeapTaskDaemon → ConcurrentGC → Alloc → Free → kswapd +``` + +### CPU调度关键词 +``` +sched_switch → sched_waking → cpu_frequency → cpu_idle +``` + +## 十一、实际应用示例 + +### 示例1:查找启动耗时 + +**搜索关键词:** +``` +startProcess +handleBindApplication +performLaunchActivity +Choreographer#doFrame +``` + +**分析步骤:** +1. 搜索 `startProcess`,找到进程启动时间 +2. 搜索 `handleBindApplication`,找到Application初始化时间 +3. 搜索 `performLaunchActivity`,找到Activity创建时间 +4. 搜索 `Choreographer#doFrame`,找到首帧时间 +5. 计算各阶段耗时 + +### 示例2:查找卡顿原因 + +**搜索关键词:** +``` +Choreographer#doFrame +performTraversals +drawFrame +dequeueBuffer +queueBuffer +``` + +**分析步骤:** +1. 搜索 `Choreographer#doFrame`,找到掉帧 +2. 查看该帧的 `performTraversals` 耗时 +3. 查看 `drawFrame` 耗时 +4. 查看 `dequeueBuffer` 和 `queueBuffer` 耗时 +5. 定位瓶颈 + +### 示例3:查找内存问题 + +**搜索关键词:** +``` +GC +HeapTaskDaemon +Alloc +kswapd +``` + +**分析步骤:** +1. 搜索 `GC`,查看GC频率 +2. 搜索 `HeapTaskDaemon`,查看GC线程活动 +3. 搜索 `Alloc`,查看内存分配模式 +4. 搜索 `kswapd`,查看内存压力 + +## 十二、总结 + +### 关键词分类 + +1. **启动相关**:进程创建、Application初始化、Activity创建、首帧渲染 +2. **渲染相关**:帧调度、视图系统、RenderThread、SurfaceFlinger、GPU +3. **系统服务**:ActivityManager、WindowManager、Input、Binder +4. **进程线程**:进程名称、线程名称 +5. **性能指标**:CPU、内存、I/O、网络 +6. **SQL查询**:表名、字段、查询模式 + +### 使用建议 + +1. **建立关键词库**:根据常用场景建立关键词库 +2. **快速定位**:使用关键词快速定位问题 +3. **组合使用**:结合搜索、筛选、SQL查询等多种方式 +4. **持续积累**:在实际使用中不断积累新的关键词 + +--- + +*最后更新:2024年* diff --git a/mkdocs.yml b/mkdocs.yml index 1c5ef5d..fb5d292 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -86,6 +86,8 @@ nav: - 学习笔记/perfeto看trace技巧.md - 学习笔记/perfetto的使用技巧.md - 学习笔记/看应用卡顿问题.md + - 学习笔记/perfetto分析trace提效的办法或者方案.md + - 学习笔记/perfetto看trace关键词.md - Obsidian笔记: - Obsidian/2026-01-05 个人文档管理.md - Obsidian/高频命令.md