Perfetto使用教程

2023-11-05  本文已影响0人  修塔寻千里

Perfetto 是谷歌开发的用于性能检测和跟踪分析的生产级开源堆栈。它提供用于记录系统级和应用程序级跟踪的服务和库,包括本机 + Java堆分析,使用SQL分析跟踪数据的C++库以及基于Web的可视化UI,能够清晰地展示GB级别体量的跟踪数据。Perfetto 适用于Linux内核和Android的整个系统范围内的性能数据收集、可视化及数据分析。


开启设备追踪

Android 11 (R)及以上默认开启Perfetto,Android 9 (P)和10 (Q) 需要手动开启,其他设备暂不支持:

# Needed only on Android 9 (P) and 10 (Q) on non-Pixel phones.
adb shell setprop persist.traced.enable 1

启动抓取方式

通过脚本工具tools/record_android_trace,使用命令行工具启动设备抓取

 adb shell perfetto [ --time TIMESPEC ] [ --buffer SIZE ] [ --size SIZE ]
    [ ATRACE_CAT | FTRACE_GROUP/FTRACE_NAME]...

通过抓取页面Perfetto UI

Perfetto UI抓取简介

Recording settings

三种录制设置,适用不同的使用场景

Stop when full

Ring buffer

该模式只会收到Max duration的影响,时间到了就停止抓取trace,但是trace会有被overwrite的风险。


Long trace

用于长时间地抓取trace,但是由于需要定时将buffer中的trace写到文件里面去,会有IO的影响。
Flush on disk every
间隔多长时间将buffer中的trace写入到文件,这个数值不能太大也不能太小,太大容易丢trace,太小容易出现IO问题。trace的停止主要受控于Max duration,或者手动停止。


CPU

CPU相关的常见功能统计


GPU

记录GPU的主频和内存使用


Power

Memory

Android apps & svcs

Chrome

如果需要分析webview相关的性能问题,可以开启该选项的相关功能


Stack Samples

Advanced settings

目前只有一个开启ftrace功能,用于分析内核性能问题,可以选择相应的tag进行记录


Recording command

配置汇总和执行,完成上述参数配置后,可以在改选项中获得所有的配置参数,拷贝命令,直接adb开启录制追踪。


adb shell perfetto \
  -c - --txt \
  -o /data/misc/perfetto-traces/trace \
<<EOF

buffers: {
    size_kb: 63488
    fill_policy: DISCARD
}
buffers: {
    size_kb: 2048
    fill_policy: DISCARD
}
data_sources: {
    config {
        name: "android.packages_list"
        target_buffer: 1
    }
}
data_sources: {
    config {
        name: "android.log"
        android_log_config {
            log_ids: LID_KERNEL
            log_ids: LID_DEFAULT
            log_ids: LID_RADIO
            log_ids: LID_SECURITY
            log_ids: LID_STATS
            log_ids: LID_SYSTEM
        }
    }
}
data_sources: {
    config {
        name: "linux.perf"
        perf_event_config {
            timebase {
                frequency: 100
                timestamp_clock: PERF_CLOCK_BOOTTIME
            }
            callstack_sampling {
            }
        }
    }
}
data_sources: {
    config {
        name: "org.chromium.trace_event"
        chrome_config {
            trace_config: "{\"record_mode\":\"record-until-full\",\"included_categories\":[\"accessibility\",\"audio\",\"aogh\",\"android_webview.timeline\",\"android_webview\",\"disabled-by-default-audio-worklet\",\"disabled-by-default-animation-worklet\",\"disabled-by-default-blink.debug\",\"log\",\"toplevel\",\"toplevel.flow\",\"scheduler\",\"sequence_manager\",\"disabled-by-default-toplevel.flow\",\"disabled-by-default-ipc.flow\",\"mojom\",\"v8\",\"blink\",\"cc\",\"gpu\",\"viz\",\"ui\",\"views\",\"benchmark\",\"evdev\",\"input\",\"loading\",\"net\",\"netlog\",\"navigation\",\"browser\"],\"excluded_categories\":[\"*\"],\"memory_dump_config\":{}}"
            privacy_filtering_enabled: true
            client_priority: USER_INITIATED
        }
    }
}
data_sources: {
    config {
        name: "track_event"
        chrome_config {
            trace_config: "{\"record_mode\":\"record-until-full\",\"included_categories\":[\"accessibility\",\"audio\",\"aogh\",\"android_webview.timeline\",\"android_webview\",\"disabled-by-default-audio-worklet\",\"disabled-by-default-animation-worklet\",\"disabled-by-default-blink.debug\",\"log\",\"toplevel\",\"toplevel.flow\",\"scheduler\",\"sequence_manager\",\"disabled-by-default-toplevel.flow\",\"disabled-by-default-ipc.flow\",\"mojom\",\"v8\",\"blink\",\"cc\",\"gpu\",\"viz\",\"ui\",\"views\",\"benchmark\",\"evdev\",\"input\",\"loading\",\"net\",\"netlog\",\"navigation\",\"browser\"],\"excluded_categories\":[\"*\"],\"memory_dump_config\":{}}"
            privacy_filtering_enabled: true
            client_priority: USER_INITIATED
        }
        track_event_config {
            disabled_categories: "*"
            enabled_categories: "accessibility"
            enabled_categories: "audio"
            enabled_categories: "aogh"
            enabled_categories: "android_webview.timeline"
            enabled_categories: "android_webview"
            enabled_categories: "disabled-by-default-audio-worklet"
            enabled_categories: "disabled-by-default-animation-worklet"
            enabled_categories: "disabled-by-default-blink.debug"
            enabled_categories: "log"
            enabled_categories: "toplevel"
            enabled_categories: "toplevel.flow"
            enabled_categories: "scheduler"
            enabled_categories: "sequence_manager"
            enabled_categories: "disabled-by-default-toplevel.flow"
            enabled_categories: "disabled-by-default-ipc.flow"
            enabled_categories: "mojom"
            enabled_categories: "v8"
            enabled_categories: "blink"
            enabled_categories: "cc"
            enabled_categories: "gpu"
            enabled_categories: "viz"
            enabled_categories: "ui"
            enabled_categories: "views"
            enabled_categories: "benchmark"
            enabled_categories: "evdev"
            enabled_categories: "input"
            enabled_categories: "loading"
            enabled_categories: "net"
            enabled_categories: "netlog"
            enabled_categories: "navigation"
            enabled_categories: "browser"
            enabled_categories: "__metadata"
            timestamp_unit_multiplier: 1000
            filter_debug_annotations: true
            enable_thread_time_sampling: true
            filter_dynamic_event_names: true
        }
    }
}
data_sources: {
    config {
        name: "org.chromium.trace_metadata"
        chrome_config {
            trace_config: "{\"record_mode\":\"record-until-full\",\"included_categories\":[\"accessibility\",\"audio\",\"aogh\",\"android_webview.timeline\",\"android_webview\",\"disabled-by-default-audio-worklet\",\"disabled-by-default-animation-worklet\",\"disabled-by-default-blink.debug\",\"log\",\"toplevel\",\"toplevel.flow\",\"scheduler\",\"sequence_manager\",\"disabled-by-default-toplevel.flow\",\"disabled-by-default-ipc.flow\",\"mojom\",\"v8\",\"blink\",\"cc\",\"gpu\",\"viz\",\"ui\",\"views\",\"benchmark\",\"evdev\",\"input\",\"loading\",\"net\",\"netlog\",\"navigation\",\"browser\"],\"excluded_categories\":[\"*\"],\"memory_dump_config\":{}}"
            privacy_filtering_enabled: true
            client_priority: USER_INITIATED
        }
    }
}
data_sources: {
    config {
        name: "android.heapprofd"
        target_buffer: 0
        heapprofd_config {
            sampling_interval_bytes: 4096
            continuous_dump_config {
                dump_phase_ms: 30000
                dump_interval_ms: 10000
            }
            shmem_size_bytes: 8388608
            block_client: true
        }
    }
}
data_sources: {
    config {
        name: "linux.ftrace"
        ftrace_config {
            ftrace_events: "clk/*"
            ftrace_events: "ext4/*"
            ftrace_events: "f2fs/*"
            ftrace_events: "fastrpc/*"
            ftrace_events: "i2c/*"
            ftrace_events: "irq/*"
            ftrace_events: "kmem/*"
            ftrace_events: "memory_bus/*"
            ftrace_events: "mmc/*"
            ftrace_events: "oom/*"
            ftrace_events: "power/*"
            ftrace_events: "regulator/*"
            ftrace_events: "sched/*"
            ftrace_events: "sync/*"
            ftrace_events: "task/*"
            ftrace_events: "ftrace/print"
            atrace_categories: "am"
            atrace_categories: "adb"
            atrace_categories: "aidl"
            atrace_categories: "dalvik"
            atrace_categories: "audio"
            atrace_categories: "binder_lock"
            atrace_categories: "binder_driver"
            atrace_categories: "bionic"
            atrace_categories: "camera"
            atrace_categories: "database"
            atrace_categories: "gfx"
            atrace_categories: "hal"
            atrace_categories: "input"
            atrace_categories: "network"
            atrace_categories: "nnapi"
            atrace_categories: "pm"
            atrace_categories: "power"
            atrace_categories: "rs"
            atrace_categories: "res"
            atrace_categories: "rro"
            atrace_categories: "sm"
            atrace_categories: "ss"
            atrace_categories: "vibrator"
            atrace_categories: "video"
            atrace_categories: "view"
            atrace_categories: "webview"
            atrace_apps: "*"
            buffer_size_kb: 512
            drain_period_ms: 100
        }
    }
}
duration_ms: 40000

EOF

trace 文件获取

使用 adb pull /data/misc/perfetto-traces/trace ~/trace.perfetto-trace 提取跟踪日志文件并在 Perfetto UI 中打开它。

trace文件过大加载问题

当trace文件大于1G时,Open trace file会出现oops 内存溢出无法访问。



可以使用Trace Processor来加载trace文件

# Download prebuilts (Linux and Mac only)
curl -LO https://get.perfetto.dev/trace_processor
chmod +x ./trace_processor

# Start the interactive shell
./trace_processor trace.perfetto-trace

# Start a local trace processor instance to replace wasm module in the UI
./trace_processor trace.perfetto-trace --httpd

执行./trace_processor trace.perfetto-trace --httpd后,Chrome浏览器打开 https://ui.perfetto.dev/#!/ ,会自动检测本地是否已经有trace_processor生成的HTTP SERVER(9001端口),如下图提示,请选择“YES, use loaded trace”,将自动解析 trace_processor已经加载的pftrace文件。

分析方法简介

slice 片段

对应代码中 Trace.beginSection/ATRACE_BEGIN 记录的事件,选中后会显示黑色边框


counter

计数器,记录离散的数值点,对应代码中 Trace.beginCounter/ATRACE_INT 记录的事件


CPU调度和频率

线程状态

点击片段上方线程调度信息片段(Running),可以看到线程当前运行在哪个CPU上



点击箭头 ,可以在CPU调度中看到该运行片段以及调度时延信息。



被P: /system/bin/traced_probes [1488]T: traced_probes [1488]线程唤醒,从就绪到运行延迟了 774us 792ns,再次点击箭头,可以回到原片段,这个跳转比较灵活方便。

锁竞争(lock contention)

在lock contention 片段上,可以点击上边的monitor contention来查看当前对象锁竞争发生的调用栈,如下详情中显示当前对象锁被Owner (Binder:1754_16)持有,其持锁当前运行在serviceDoneExecuting (AMS.java 16426行),且当前等待该对象锁的线程已经有5个了;当前线程执行被阻塞在getUidState方法中(AMS.java 6614行)。


SQL查询

Perfetto支持通过sql语句查询数据,提供常见的格式和关键字段信息:

Slices

横向轴上的一小段时间片段,具有指定的名称


> SELECT ts, dur, name FROM slice
ts                   dur                  name
-------------------- -------------------- ---------------------------
     261187017446933               358594 eglSwapBuffersWithDamageKHR
     261187017518340                  357 onMessageReceived
     261187020825163                 9948 queueBuffer
     261187021345235                  642 bufferLoad
     261187121345235                  153 query
     ...

Counters

根据时间记录的离散数值点



···

SELECT ts, value FROM counter
ts value


 261187012149954          1454.000000
 261187012399172          4232.000000
 261187012447402         14304.000000
 261187012535839         15490.000000
 261187012590890         17490.000000
 261187012590890         16590.000000

...
···

Scheduler slices

CPU运行的详细task


> SELECT ts, dur, cpu, utid FROM sched
ts                   dur                  cpu                  utid
-------------------- -------------------- -------------------- --------------------
     261187012170489               267188                    0                  390
     261187012170995               247153                    1                  767
     261187012418183                12812                    2                 2790
     261187012421099               220000                    6                  683
     261187012430995                72396                    7                 2791
...

参考文章

1、 https://perfetto.dev/docs/

2、https://ui.perfetto.dev/#!/record

3、https://www.cnblogs.com/treecarrybear/p/17056783.html

上一篇下一篇

猜你喜欢

热点阅读