【Android性能优化】使用 Perfetto 进行链路跟踪(Record trace)

7,718 阅读5分钟

介绍

Perfetto 是一个开源的系统性能分析工具,它可以收集和记录 Android 系统和应用程序的性能数据,并使用图形界面展示这些数据。 Perfetto 可以收集多种类型的数据,如 CPU 使用率、内存使用情况、网络流量等。它还可以跟踪应用程序的事件,如启动时间、触摸事件等。

本文介绍根据官网资料介绍一下如何使用Perfetto进行链路跟踪(Recording Trace)。

Recording Trace

开启链路跟踪服务

Perfetto基于Android平台服务,在Android9以上可用,Android11以上默认开启,因此在Android 9 - Android 10需要调用以下命令保证链路跟踪服务启用。

adb shell setprop persist.traced.enable 1

一、设备内部工具

直接使用设备上的 /system/bin/perfetto 命令工具。事先需要准备ADB工具,然后运行相关命令。

举个官方文档中的例子:

adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 20s \
sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory

sched后面会带有比较多的配置,熟悉Android Framework的话肯定对这些字段会比较熟悉,它们都是追踪的可选配置项,此处暂时先不解释这些配置。

Perfetto工具是Android设备自带的,因此无需从远端下载,但是有以下多个限制:

  1. 使用Ctrl + C通常能够结束本次链路跟踪,但是在使用adb shell perfetto的时候无法透传进去,因此会造成链路跟踪无法顺利结束,需要调用adb shell使用PTY-based交互式会话才可以使用Ctrl + C命令提前结束本次链路跟踪。
  2. 在没有root的Android 12 之前的设备中,由于SELinux 规则过度限制,只能使用cat config | adb shell perfetto -c - (-: stdin)来配置。并且Android 12之后/data/misc/perfetto-configs才可以用来存储配置。
  3. 当跟踪比较长的链路,在benchmarks或者CI,使用PID=$(perfetto --background)然后使用 kill $PID来停止。

通过该命令生成的trace文件可以通过Perfetto UI查看,先调用以下命令将生成的文件取出来:

adb pull /data/misc/perfetto-traces/trace ~/trace.perfetto-trace

在Android 10 之前的机器, adb 不可以直接pull /data/misc/perfetto-traces。只能使用adb shell cat /data/misc/perfetto-traces/trace > trace 来替代。

打开Perfetto UI页面,点击左边的Open trace file打开文件或者直接将文件拖进去,结果如下所示。

image_5qovVHdy3-.png

二、外部脚本

可以使用 tools/record_android_trace 脚本辅助trace,使用外部脚本的追踪效果和ADB工具一样,但是外部脚本可以帮助正确设置路径、自动拉取结果、自动将结果推送到浏览器 Perfetto UI 页面。

在Linux和Mac上下载该脚本:

curl -O https://raw.githubusercontent.com/google/perfetto/master/tools/record_android_trace
chmod u+x record_android_trace

使用脚本,命令和ADB类似,例如:

./record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb \
sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory

输出路径为电脑中的路径,而不是手机中的路径。

在Windows中:

curl -O https://raw.githubusercontent.com/google/perfetto/master/tools/record_android_trace
python3 record_android_trace -o trace_file.perfetto-trace -t 10s -b 32mb \
sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory

需要注意的是,该脚本为python脚本,因此电脑中需要配置好Python环境。

三、进阶配置

上述的命令行包含如下配置

sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory

如果需要进一步配置,则可以在trace的时候使用—-txt命令传入完整配置。更多配置信息可以到Trace configuration page页面查看,举个例子,调用以下命令生成一个配置文件。

cat<<EOF>config.pbtx
duration_ms: 10000

buffers: {
    size_kb: 8960
    fill_policy: DISCARD
}
buffers: {
    size_kb: 1280
    fill_policy: DISCARD
}
data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            ftrace_events: "sched/sched_switch"
            ftrace_events: "power/suspend_resume"
            ftrace_events: "sched/sched_process_exit"
            ftrace_events: "sched/sched_process_free"
            ftrace_events: "task/task_newtask"
            ftrace_events: "task/task_rename"
            ftrace_events: "ftrace/print"
            atrace_categories: "gfx"
            atrace_categories: "view"
            atrace_categories: "webview"
            atrace_categories: "camera"
            atrace_categories: "dalvik"
            atrace_categories: "power"
        }
    }
}
data_sources: {
    config {
        name: "linux.process_stats"
        target_buffer: 1
        process_stats_config {
            scan_all_processes_on_start: true
        }
    }
}
EOF

截屏2023-06-05 15.24.10_NnqZfphNqv.png

然后在record时将该文件传进去

./record_android_trace -c config.pbtx -o trace_file.perfetto-trace 

当然,也可以使用Android设备内置的perfetto工具

cat config.pbtx | adb shell perfetto -c - --txt -o /data/misc/perfetto-traces/trace.perfetto-trace

或者将该文件传进Android设备,再调用perfetto命令

adb push config.pbtx /data/local/tmp/config.pbtx
adb shell 'cat /data/local/tmp/config.pbtx | perfetto --txt -c - -o /data/misc/perfetto-traces/trace.perfetto-trace'

四、System Tracing APP

该APP为Android内置的系统应用,Android官方有对该工具比较详尽的中文描述:developer.android.com/topic/perfo…

对于Android10以上设备仍然是生成一个.perfetto-trace文件,将其取出之后可以在Perfetto UI打开。

五、Perfetto UI

这种方式是官方比较推荐、也是我比较喜欢和推荐的一种方式,一开始使用该工具先从该UI界面入手会比较简单,先放一下Perfetto UI的地址:ui.perfetto.dev/

进入该页面,点击左边的Record new trace进入记录链路的页面。

image_9DQpe4QOr9.png

此处可以设置trace的参数,可以按需选择需要record的配置项,不需要的就可以不选择。

image_L-bQ4ruPuY.png

选完之后点击Recording command,可以查看到一串命令,而这个命令其实就是第一种方式的命令,但是没有采用简单的参数配置,而是使用了比较复杂的参数配置。

image_-jy3cXBC0N.png

复制参数到Terminal中调用是和右上角的Start Recording按钮的效果是一样的。

如果没有Start Recording按钮,可以点击Add ADB Device连接设备,连接上了就可以开始记录。需要注意的是,如果当前正在使用其他方式连接设备(例如正在使用Android Studio连接设备),会导致录制失败,需要停止其他方式的连接。

点击按钮并成功记录,会自动打开录制好的文件,和使用外部脚本的行为一致。

image_6pNra5QsOu.png

总结

Perfetto是一个比较新的也是官方推荐的工具,只支持Android9以上,使用的方式多种多样,算是比较友好了。它也可以用于dump Java内存、本地内存、本地内存符号翻译等等。本文只是简单介绍如何使用,而关于获得了结果文件之后如何分析卡顿、内存泄露、ANR等等,不同的项目分析方式不一样,还需要更多的实践经验才能熟练掌握。

参考