【用法总结】Systrace使用基础

1,543 阅读7分钟

一、systrace基本介绍

    systrace是Android Sdk提供的一个用于分析系统及应用性能的工具。     目前platform-tools最新版本是33.0.3 在这里插入图片描述 在这里插入图片描述 从33.0.1开始systrace被移除,所以需要下载安装33.0.1的前一个版本33.0.0,下载地址

platform-tools工具路径是在:android_sdk\platform-tools platform-tools的文件夹结构 ps: 需要下载指定版本的platform-tools工具,可通过:***dl.google.com/android/rep…

被弃用了?

官方最新已经推荐使用perfetto工具了,但是在使用方式上也是基于systrace差不多的模式,并且日常使用还是可以用systrace的,主要看能否满足日常需要,并不是一定要用最新的工具。

二、快捷键用法

二、systrace命令用法

    使用下文说明的命令格式,然后在chrome浏览器中,输入:chrome://tracing/,然后点击load选择导出的.html文件即可。 在这里插入图片描述

2.1 命令格式:

切换systrce.py文件所在的目录,然后执行如下命格式:

python systrace.py [options] [category1] [category2] ... [categoryN]

2.2 option取值:

option说明
-a后跟应用包名,指定抓取的应用报名
-o后跟文件路径,说明导出到哪个路径,文件名是什么
-t N, –time=N抓取时长,默认是5s
-b N, -buf-size=Nbuffer的大小(单位:KB),用于限制trace总大小,默认无上限,注意这里限制小了会导致trace抓不全
-from-file=<FROM_FILE>如果是用atrace直接在shell命令环境中抓取的atrace文件,则需要用这个选项,加上-o <FILE_PATH>来转换成.html后缀的文件,然后用chrome浏览chrome://tracing/去浏览分析trace
-l, --list-categories查看所有可用的category(可抓取的trace维度,比如:am、wm、view、gfx等等)

2.3 category取值:

category说明
gfx图形信息,加上能看到主线程的doFrame和RenderThread的drawFrame过程
schedcpu调度信息
view视图相关,加上这个就能看到View的测量,布局文件的inflate过程
amActivity Manager服务,加上这个就能看到Application、Activity的启动过过程了
wm窗口管理服务
app应用信息,实测好多设备都不支持这个category了
webviewWebView相关信息

2.4 命令用法举例:

  • 查看当前设备支持的category类型:
// 这里要注意和Android系统自带的atrace命令区分开,atrace查看所有的category的命令是:atrace --list_categories
// 前者是横线分隔单词:--list-categories,后者是下划线分隔单词:--list_categories
python systrace.py --list-categories

这里要注意和Android系统自带的atrace命令区分开,atrace查看所有的category的命令是:atrace --list_categories, 前者是横线分隔单词:--list-categories,后者是下划线分隔单词:--list_categories

例如:

admin@adminMacBook-Pro systrace % python systrace.py --list-categories
         gfx - Graphics
       input - Input
        view - View System
     webview - WebView
          wm - Window Manager
          am - Activity Manager
          sm - Sync Manager
       audio - Audio
       video - Video
      camera - Camera
         hal - Hardware Modules
         res - Resource Loading
      dalvik - Dalvik VM
          rs - RenderScript
      bionic - Bionic C Library
       power - Power Management
          pm - Package Manager
          ss - System Server
    database - Database
     network - Network
         adb - ADB
    vibrator - Vibrator
        aidl - AIDL calls
       nnapi - NNAPI
         rro - Runtime Resource Overlay
         pdx - PDX services
       sched - CPU Scheduling
         irq - IRQ Events
        freq - CPU Frequency
        idle - CPU Idle
        disk - Disk I/O
        sync - Synchronization
  memreclaim - Kernel Memory Reclaim
  binder_driver - Binder Kernel driver
  binder_lock - Binder global lock trace
     thermal - Thermal event
         gfx - Graphics (HAL)
         ion - ION allocation (HAL)

NOTE: more categories may be available with adb root
  • 抓取com.yyg.anr应用的trace:
python systrace.py -a com.yyg.anr -t 5 -o anr_trace.html sched freq idle am wm gfx view binder_driver hal dalvik camera input res

2.5 快捷键用法:

(1)WASD:W/S:放大/缩小,A/D: 时间轴向左向右移动,同时摁住shift+W/A/S/D时会增加速度 (2)M:聚焦当前选中的区域,并在下方展示具体的耗时 (3)F:放大当前选区 (4)V:高亮Vsync信号 (5)左键/右键:上一个事件,下一个事件

三、systrace报告怎么看?

3.1 CPU调度信息

3.2 线程状态信息

线程状态信息

3.2.1 绿色 : 运行中(Running)

绿色:Running状态

3.2.1 蓝色:Runanble状态

蓝色:Runanble状态

3.2.1 白色:Sleeping状态

白色:Sleeping状态 线程没有工作要做,可能是因为线程在互斥锁上被阻塞。 作用:这里一般是在等事件驱动

3.2.1 橘色:不可中断的睡眠态 (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 操作都需要等待排队时, 极其容易出现且阻塞的时间往往会比较长. 比如com.miui.notification:remote进程有这样的状态: 橘色:不可中断的睡眠态 (Uninterruptible Sleep - IO Block)

3.2.1 紫色 : 不可中断的睡眠态(Uninterruptible Sleep)

紫色 : 不可中断的睡眠态(Uninterruptible Sleep) 线程在另一个内核操作(通常是内存管理)上被阻塞。 作用:一般是陷入了内核态,有些情况下是正常的,有些情况下是不正常的,需要按照具体的情况去分析

3.3 线程唤醒信息:

线程唤醒信息6360线程处于Runanble状态时,蓝色的线程状态区域,是被6456线程唤醒,继续看这个线程是干什么的。 虽然这个线程只能看到tid=6456,但是根据硬件加速打开状态,并且这个线程是紧接着doFrame做drawFrame操作的,可以推断这个是RenderThread线程。 6456线程是RenderThread线程 🤨:并不是每个Runnable状态的时间段都能看到唤醒线程,为什么? 推测并不一定是等待同步锁对象导致的Runnable状态,也可能是CPU时间片没分配到。

3.4 帧率信息

帧率信息主要看主线程的doFrame和RenderThread线程drawFrame的trace进行分析。 主线程的doFrame和RenderThread线程drawFrame的trace 每一帧就是一个F圆圈,代表调用Choreographer(编舞者)的doFrame()方法耗时

  • 圆圈绿色代表Frame渲染流畅
  • 黄色和红色代表渲染超过16.6ms,红色的更严重。 圆圈绿色代表Frame渲染流畅,黄色和红色代表渲染超过16.6ms,红色的更严重
  • perfetto分析trace上是没有⭕️的,这时候可以选中一段时间,然后看看doFrame+drawFrame执行了多少次,计算出平均帧率分析卡顿程度

3.5 应用启动耗时分析

分析应用启动主要看trace上以下几个阶段: 应用启动几大核心阶段: 应用启动几大核心阶段

四、总结

trace的使用很容易,但在实际分析性能问题又很容易陷入“好像知道该怎么分析,但是实际上又分析不出来个所以然的情况”,其实究其根本还是如下两个关键点:

4.1 trace的每一项信息代表的含义一知半解,不明确

4.2 先熟悉运行逻辑方知如何分析

    比如分析卡顿丢帧的trace时,发现主线程的CPU状态有一段时间是Runnable或着sleep状态的,然后根据3.3节介绍的查看唤醒信息时,跟踪到是被RenderThread线程唤醒的,也就是说主线程会因为渲染线程在执行某个任务导致主线程等待。再继续推测很可能是渲染线程上一帧绘制卡了导致没法绘制下一帧,也能看出主线程和渲染线程是有协作关系的,这就需要我们熟悉界面每一帧从测量、布局到绘制,再到传给渲染线程,渲染线程通过c/c++调用到GPU绘制展示到显示器上的过程,否则是很难分析出来根因的,更不知道该怎么修复问题。 界面绘制过程图

    再比如说分析应用启动慢问题的trace时,得先知道应用冷启动过程是什么流程,哪些节点是我们能干预的?那么我们就需要先熟悉以下过程:

应用进程不存在的情况下,从点击桌面应用图标,到应用启动,大概会经历以下流程:

  • 1、Launcher startActivity
  • 2、AMS startActivity
  • 3、Zygote fork进程
  • 4、ActivityThread main()
    • 4.1 ActivityThread attach
    • 4.2 handleBindApplication
    • 4.3 attachBaseContext
    • 4.4 installContentProviders
    • 4.5 Application onCreate
  • 5、ActivityThread进入loop循环
  • 6、Activity生命周期回调,onCreate、onStart、onResume... 整个流程我们能干预的主要是4.3、4.5和6,那么就需要重点关注trace中这几个节点的tag进行分析。

参考文章

[1] Android Systrace 基础知识 -- 分析 Systrace 预备知识 [2] Android卡顿掉帧问题分析之工具篇