Perfetto简易入门

一、Perfetto基础

1、Perfetto介绍

Perfetto 是一个生产级的开源堆栈,用于提高性能 仪器和痕量分析。与 Systrace 不同,它提供数据源超集,可以用 protobuf 编码的二进制流形式记录任意长度的跟踪记录。可以将Perfetto理解为systrace的升级版,用在更新的平台、新图表展示更多的信息。它可帮助开发者收集 Android 关键子系统(如SurfaceFlinger/SystemServer/Input/Display 等 Framework 部分关键模块、服务,View系统等)的运行信息,从而帮助开发者更直观的分析系统瓶颈,改进性能。

e4dfec5885de4f87ae55be1c0561ab23.png

其基本功能包括以下几部分:

 关于Perfetto的官方介绍和使用可以看这里:perfetto官网

2、Perfetto 使用流程

使用 Perfetto 前,要先了解一下 Perfetto 在各个平台上的使用方法,基本流程如下:

  • 手机准备好你要进行抓取的界面
  • 点击开始抓取(命令行的话就是开始执行命令)
  • 手机上开始操作(不要太长时间,文件太大会很卡,而且不好定位问题)
  • 设定好的时间到了之后,会将生成 xxxtrace.html 文件,使用如下网站打开Perfetto UI

一般抓到的 Perfetto 文件如下

39fb2eb474ff4e2eb19671c9df767c30.png

3、抓取Trace的几种方式

3.1、命令抓取perfetto-traces方式
命令行形式比较灵活,速度也比较快,相关的TAG一次性配置好之后,以后再使用的时候就会很快就出结果,也可以把相关命令写成脚本,下次使用会比较方便。

命令相关的参数虽然比较多,但使用工具的时候不需考虑这么多,在对应的项目前打钩即可,命令行的时候才会去手动加参数

一般来说比较常用的是

-o : 指示输出文件的路径和名字
-t : 抓取时间(最新版本可以不用指定, 按 Enter 即可结束)
-b : 指定 buffer 大小 (一般情况下,默认的 Buffer 是够用的,如果你要抓很长的 Trae , 那么建议调大 Buffer )
-a : 指定 app 包名 (如果要 Debug 自定义的 Trace 点, 记得要加这个)

在低于Android R的版本上面默认是关闭的,需要先执行命令打开:

adb shell setprop persist.traced.enable 1
  
AI写代码 java
运行

基本抓取并导出perfetto-traces命令如下,需要其他tag或者相关命令可以自行加入:


  
  1. 抓取perfetton:
  2. adb shell perfetto -o /data/misc/perfetto-traces/trace_file.perfetto-trace -t 10s sched freq idle am wm gfx view binder_driver hal dalvik camera input res memory
  3. 导出trace文件:
  4. adb pull /data/misc/perfetto-traces/trace_file.perfetto-trace
AI写代码 java
运行

3.2 使用atrace命令抓取systrace,具体方法如下:


  
  1. 抓取atrace命令
  2. adb shell atrace -z -b 40000 am wm view res ss gfx view halbionic pm sched freq idle disk load sync binder_driver binder_lock memreclaim dalvik input -t 10 > /data/local/tmp/trace_output.atrace
  3. pull导出trace文件
  4. adb pull /data/local/tmp/trace_output.atrace
AI写代码 java
运行

3.3 使用systrace脚本抓取systrace,具体方法如下:

1、需要配置好python环境。

2、解压systrace.zip。

进入到解压后的systrace目录下,此时该目录下可以找到systrace.py文件,执行如下命令:

python systrace.py am wm view res ss gfx rs hal bionic pm sched freq idle disk binder_driver binder_lock memreclaim dalvik input database -t 10 -o tracelog\systrace.html

  
AI写代码 python
运行

在systrace目录下的tracelog目录中查找生成的systrace.html文件。

3.4 通过手机里的System Tracing抓取

1、打开“开发者选项”,点击Settings->System->Developer options->System Tracing->ShowQuick Settings tile,添加system tracing的快捷图标。 

在设置——系统——开发者选项——系统跟踪(不同软件可能路径不太一样)中设置需要录制的类别(Categories)、缓冲区大小(Buffer Size)

打开【录制跟踪记录】(Record trace)开始录制

弹出通知后即可开始复现问题或是进行特定操作

完成以后点击通知栏中的【点按即可停止跟踪】(Tap to stop tracing)即可停止并保存

2、测试前,点击下拉状态栏中Record trace图标开始抓取perfetto-trace,然后开始测试。

3、完成测试后,点击“下拉状态栏中的Record trace图标”或者“下拉状态栏中的正在抓取的通知”停止systrace的抓取。

4、弹出“trace saved”的通知后,可在手机目录/data/local/traces中获取抓取的perfetto-trace文件。

5、通过命令adb pull /data/local/traces将对应的systrace保存到本地。

4、查看线程状态

Perfetto 会用不同的颜色来标识不同的线程状态, 在每个方法上面都会有对应的线程状态来标识目前线程所处的状态,通过查看线程状态我们可以知道目前的瓶颈是什么, 是 cpu 执行慢还是因为 Binder 调用, 又或是进行 io 操作, 又或是拿不到 cpu 时间片

线程状态主要有下面几个

4.1 绿色 : 运行中(Running)

只有在该状态的线程才可能在 cpu 上运行。而同一时刻可能有多个线程处于可执行状态,这些线程的 task_struct 结构被放入对应 cpu 的可执行队列中(一个线程最多只能出现在一个 cpu 的可执行队列中)。调度器的任务就是从各个 cpu 的可执行队列中分别选择一个线程在该cpu 上运行

作用:我们经常会查看 Running 状态的线程,查看其运行的时间,与竞品做对比,分析快或者慢的原因:

  1. 是否频率不够?
  2. 是否跑在了小核上?
  3. 是否频繁在 Running 和 Runnable 之间切换?为什么?
  4. 是否频繁在 Running 和 Sleep 之间切换?为什么?
  5. 是否跑在了不该跑的核上面?比如不重要的线程占用了超大核

3ed588e0fc0c4836bd41b11617403dd5.png

4.2 蓝色 : 可运行(Runnable)

线程可以运行但当前没有安排,在等待 cpu 调度

作用:Runnable 状态的线程状态持续时间越长,则表示 cpu 的调度越忙,没有及时处理到这个任务:

  1. 是否后台有太多的任务在跑?
  2. 没有及时处理是因为频率太低?
  3. 没有及时处理是因为被限制到某个 cpuset 里面,但是 cpu 很满?
  4. 此时 Running 的任务是什么?为什么?

a1053015b6374b6d80cfff4abe9fdc27.png

4.3 白色 : 休眠中(Sleep)

线程没有工作要做,可能是因为线程在互斥锁上被阻塞,也可能等待某个线程返回,可以看是被谁唤醒,去查看是等待哪个线程。

作用 : 这里一般是在等事件驱动

54f92113c89e473c9f31672f9cc69fed.png

4.4 橘色 : 不可中断的睡眠态 (Uninterruptible Sleep - IO Block)

线程在I / O上被阻塞或等待磁盘操作完成,一般底线都会标识出此时的 callsite :wait_on_page_locked_killable

作用:这个一般是标示 io 操作慢,如果有大量的橘色不可中断的睡眠态出现,那么一般是由于进入了低内存状态,申请内存的时候触发 pageFault, linux 系统的 page cache 链表中有时会出现一些还没准备好的 page(即还没把磁盘中的内容完全地读出来) , 而正好此时用户在访问这个 page 时就会出现 wait_on_page_locked_killable 阻塞了. 只有系统当 io 操作很繁忙时, 每笔的 io 操作都需要等待排队时, 极其容易出现且阻塞的时间往往会比较长.

332b720984ef417ab822426e2944e4d6.png

4.5 棕色 : 不可中断的睡眠态( Uninterruptible Sleep (non-IO))

线程在另一个内核操作(通常是内存管理)上被阻塞。

作用:一般是陷入了内核态,有些情况下是正常的,有些情况下是不正常的,需要按照具体的情况去分析

1cdc102cc9e94f56a84c89eb03d615ff.png

5、任务唤醒信息分析

Perfetto 会标识出一个非常有用的信息,可以帮助我们进行线程调用等待相关的分析。

一个线程被唤醒的信息往往比较重要,知道他被谁唤醒,那么我们也就知道了他们之间的调用等待关系,如果一个线程出现一段比较长的 sleep 情况,然后被唤醒,那么我们就可以去看是谁唤醒了这个线程,对应的就可以查看唤醒者的信息,看看为什么唤醒者这么晚才唤醒。

一个常见的情况是:应用主线程程使用 Binder 与 SystemServer 的 AMS 进行通信,但是恰好 AMS 的这个函数正在等待锁释放(或者这个函数本身执行时间很长),那么应用主线程就需要等待比较长的时间,那么就会出现性能问题,比如响应慢或者卡顿,这就是为什么后台有大量的进程在运行,或者跑完 Monkey 之后,整机性能会下降的一个主要原因

另外一个场景的情况是:应用主线程在等待此应用的其他线程执行的结果,这时候线程唤醒信息就可以用来分析主线程到底被哪个线程 Block 住了,如下场景:

81e29307f4a742058b94e375f068f243.png

 我们可以看到这段slepping状态这段时间,我们可以点击后面段Runnig状态,查看它运行在哪个CPU上,点击后可以看到是哪个线程唤醒它的,就可以看是否有异常情况了。

d12015f858f049068b99c65896160f9d.png

6、信息区数据解析

6.1 CPU架构

简单来说目前的手机 CPU 按照核心数和架构来说,可以分为下面三类:

  1. 非大小核架构(正常所以核一样)
  2. 大小核架构(正常0-3小核,4-7大核)
  3. 大中小核架构(正常0-3小核,4-6中核,7超大核)

6.2 CPU Info信息

Pefetto 中CPU Info信息一般在最上面,里面经常会用到的信息包括:

  1. CPU 频率变化情况
  2. 任务执行情况
  3. 大小核的调度情况
  4. CPU Boost 调度情况

总的来说,Systrace 中的 Kernel CPU Info 这里一般是看任务调度信息,查看是否是频率或者调度导致当前任务出现性能问题,举例如下:

  1. 某个场景的任务执行比较慢,我们就可以查看是不是这个任务被调度到了小核?
  2. 某个场景的任务执行比较慢,当前执行这个任务的 CPU 频率是不是不够?
  3. 我的任务比较特殊,能不能把我这个任务放到大核去跑?
  4. 我这个场景对 CPU 要求很高,我能不能要求在我这个场景运行的时候,限制 CPU 最低频率?

ea5c637a74ec40d8a66cc0b2e038bcfb.png

6.3 Current Selection信息解析:

64cd87a622da479fa31009306dd7ee19.png 

6.4 CPU by thread信息解析

89e150b6a65747e6a1938f6746517140.png

7、快捷键使用

快捷键的使用可以加快查看 Perfetto 的速度,下面是一些常用的快捷键

W : 放大 Perfetto , 放大可以更好地看清局部细节
S : 缩小 Perfetto, 缩小以查看整体
A : 左移
D : 右移
M : 选中该时间段的范围,方便上下查看

用pefetto自带的搜索框需要4个字符以上,搜出来的数据会比较详细,可以配合Ctrl+F一起使用,有时候Ctrl+F搜索不到的数据,需要自带的Search搜索

97100415370043598ca1d85e2c7a6ead.png

8、何为刷新率
  1. 60 fps 的意思是说,画面每秒更新60次,是针对软件的
  2. 这60次更新,是要均匀更新的,不是说一会快,一会慢,那样视觉上也会觉得不流畅
  3. 每秒60次,也就是 1/60 ~= 16.67 ms 要更新一次
  4. 这里说的屏幕的刷新率,是针对硬件的,现在大部分手机屏幕的刷新率,都维持在60 HZ,移动设备上一般使用60HZ,是因为移动设备对于功耗的要求更高,提高手机屏幕的刷新率,对于手机来说,逻辑功耗会随着频率的增加而线性增大,同时更高的刷新率,意味着更短的TFT数据写入时间,对屏幕设计来说难度更大。

二、主线程与渲染线程

1、主线程的创建

Android App 的进程是基于 Linux 的,其管理也是基于 Linux 的进程管理机制,所以其创建也是调用了 fork 函数

frameworks/base/core/jni/com_android_internal_os_Zygote.cpp

pid_t pid = fork();
  
AI写代码 cpp
运行

Fork 出来的进程,我们这里可以把他看做主线程,但是这个线程还没有和 Android 进行连接,所以无法处理 Android App 的 Message ;由于 Android App 线程运行基于消息机制 ,那么这个 Fork 出来的主线程需要和 Android 的 Message 消息绑定,才能处理 Android App 的各种 Message

这里就引入了 ActivityThread ,确切的说,ActivityThread 应该起名叫 ProcessThread 更贴切一些。ActivityThread 连接了 Fork 出来的进程和 App 的 Message ,他们的通力配合组成了我们熟知的 Android App 主线程。所以说 ActivityThread 其实并不是一个 Thread,而是他初始化了 Message 机制所需要的 MessageQueue、Looper、Handler ,而且其 Handler 负责处理大部分 Message 消息,所以我们习惯上觉得 ActivityThread 是主线程,其实他只是主线程的一个逻辑处理单元。

1.1 ActivityThread 的创建

App 进程 fork 出来之后,回到 App 进程,查找 ActivityThread 的 Main函数

com/android/internal/os/ZygoteInit.java


  
  1. static final Runnable childZygoteInit (
  2. int targetSdkVersion, String[] argv, ClassLoader classLoader) {
  3. RuntimeInit. Arguments args = new RuntimeInit.Arguments(argv);
  4. return RuntimeInit.findStaticMain(args.startClass, args.startArgs, classLoader);
  5. }
AI写代码 java
运行

这里的 startClass 就是 ActivityThread,找到之后调用,逻辑就到了 ActivityThread的main函数

android/app/ActivityThread.java


  
  1. public static void main (String[] args) {
  2. //1. 初始化 Looper、MessageQueue
  3. Looper.prepareMainLooper();
  4. // 2. 初始化 ActivityThread
  5. ActivityThread thread = new ActivityThread();
  6. // 3. 主要是调用 AMS.attachApplicationLocked,同步进程信息,做一些初始化工作
  7. thread.attach( false, startSeq);
  8. // 4. 获取主线程的 Handler,这里是 H ,基本上 App 的 Message 都会在这个 Handler 里面进行处理
  9. if (sMainThreadHandler == null) {
  10. sMainThreadHandler = thread.getHandler();
  11. }
  12. // 5. 初始化完成,Looper 开始工作
  13. Looper.loop();
  14. }
AI写代码 java
运行

main 函数处理完成之后,主线程就算是正式上线开始工作,其 Perfetto 流程如下: 

9212982063fd43c283730b0d0e955b01.png 

1.2 ActivityThread 的功能

另外我们经常说的,

<think>嗯,用户想了解Perfetto性能分析工具的介绍和使用方法。首先,我需要确认用户的需求是什么。他们可能是一个开发者,或者是对性能优化感兴趣的人,想要学习如何使用Perfetto来分析应用的性能问题。接下来,我得整理Perfetto的基本信息,比如它的定义、主要功能和特点。然后是关于使用方法的步骤,可能需要分点说明,比如如何开启调试模式、录制性能数据、分析数据等。还要考虑用户可能遇到的问题,比如如何安装Perfetto,或者如何解读数据结果。此外,用户提供的引用材料里提到了Perfetto可以结合systrace和logcat,以及分析内存问题,这些信息需要整合到回答中。同时,用户示例中的相关问题部分,我应该生成几个相关的问题,比如与其他工具的比较、常见问题解决方法、内存分析步骤等。要确保回答结构清晰,符合用户要求的格式,使用中文,数学公式用$...$,独立公式用$$...$$。另外,注意引用标识的正确添加,比如在提到性能分析工具时引用[^1]和[^2]。最后,检查LaTeX语法是否正确,避免格式错误。可能还需要考虑用户的实际使用场景,比如在Android开发中的应用,或者系统级性能分析,从而给出具体的操作步骤或示例。总之,回答需要全面覆盖Perfetto的介绍和使用方法,同时引导用户进一步探索相关问题。</think>### Perfetto性能分析工具介绍 Perfetto 是一款开源的系统级性能分析工具,由Google主导开发,主要用于Android和Linux系统的性能跟踪与分析。它集成了多种功能,包括**CPU调度、内存分配、进程状态、文件I/O、网络活动**等维度的数据采集与分析。其核心优势在于: 1. **多数据源整合**:支持将系统调用(systrace)、日志(logcat)、内核事件等数据统一在时间轴上展示。 2. **高效低开销**:采用零拷贝环形缓冲区技术,减少对系统性能的影响。 3. **跨平台支持**:可通过Web UI或本地工具链分析数据,兼容Windows、macOS和Linux。 #### 核心功能对比 $$ \begin{array}{|c|c|c|} \hline \text{功能} & \text{Systrace} & \text{Perfetto} \\ \hline \text{数据整合} & \text{仅系统调用} & \text{系统调用+日志+内存} \\ \hline \text{内存分析} & \text{不支持} & \text{支持ion/dma_buf泄漏检测} \\ \hline \text{可视化} & \text{独立工具} & \text{Web UI交互式分析} \\ \hline \end{array} $$ ### 使用方法详解 #### 1. 启用调试模式 ```bash # Android设备需开启跟踪服务 adb shell setprop persist.traced.enable 1 ``` #### 2. 录制性能数据 通过**Perfetto配置文件**(`.pbtx`)定义采集规则: ```text duration_ms: 10000 buffers: { size_kb: 8960 fill_policy: DISCARD } data_sources: { config { name: "linux.process_stats" target_buffer: 0 } } ``` #### 3. 数据采集与导出 ```bash # 启动录制(生成trace.pb文件) adb shell perfetto --config :test --out /data/misc/perfetto-traces/trace.pb # 导出到本地分析 adb pull /data/misc/perfetto-traces/trace.pb ``` #### 4. 数据分析技巧 - **时间轴缩放**:使用`WASD`键快速导航 - **切片查询**:在搜索框输入`slice_name = "binder_transaction"` - **内存统计**:点击`Memory`面板查看进程的**RSS**和**Swap**变化 ### 典型案例分析 在Android应用启动优化中,通过Perfetto可发现: 1. **主线程阻塞**:定位`Choreographer#doFrame`耗时 2. **IPC调用堆积**:分析`binder_transaction`的调用链 3. **内存抖动**:检测`malloc/free`高频调用区域[^2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值