Systrace

因为最近用的比较多,专

一、 Systrace

Systrace 是Android4.1中新增的性能数据采样和分析工具,它可帮助开发者收集Android关键子系统

如SurfaceFlinger、WindowManagerService等Framework部分关键模块、服务、View系统等

Google IO 2017上更是对其各种强推。Systrace其实和TraceView很像,都是统计一些方法(或者是一个执行阶段)的耗时,然后在一个有时间轴的图表上展示出来。不同的是,TraceView是收集所有方法的耗时信息和嵌套关系,这使得TraceView本身的性能消耗很大,反而影响了实际的运行环境。Systrace则采用了不同的思路,通过有限的Label先粗略统计出一个阶段的耗时,定位到问题以后,在慢慢细化和进一步测算分析。

监视和跟踪Android系统的行为:

1.CPU周期都用在哪里

2.每个线程、进程在指定时间内都在干嘛。

3.功能包括跟踪系统的I/O操作、内核工作队列、CPU负载以及Android各个子系统的运行状况等

4. 会突出观测到的问题,从垃圾回收到渲染内容都可能是问题对象,甚至提供给你建议的解决方案。

它主要由3部分组成:

  • 内核部分:Systrace利用了Linux Kernel中的ftrace功能,所以,如果要使用Systrace的话,必须开启kernel中和ftrace相关的模块。
  • 数据采集部分:Android定义了一个Trace类,应用程序可利用该类把统计信息输出给ftrace。同时,Android还有一个atrace程序,它可以从ftrace中读取统计信息然后交给数据分析工具来处理。
  • 数据分析工具:Android提供一个systrace.py(python脚本文件,位于Android SDK目录/tools/systrace中,其内部将调用atrace程序)用来配置数据采集的方式(如采集数据的标签、输出文件名等)和收集ftrace统计数据并生成一个结果网页文件供用户查看。从本质上说,Systrace是对Linux Kernel中ftrace的封装。应用进程需要利用Android提供的Trace类来使用Systrace。

常用标签

不论是DDMS还是命令行,都可以在启动trace前指定采集哪些系统预置的标签。下面把一些常用的标签类别列举如下:

  • Graphics: Graphic系统的相关信息,包括SerfaceFlinger,VSYNC消息,Texture,RenderThread等;分析卡顿非常有效。
  • Input:
  • View System: View绘制系统的相关信息,比如onMeasure,onLayout等;对分析卡顿比较有帮助。
  • Window Manager:
  • Activity Manager: ActivityManager调用的相关信息;用来分析Activity的启动过程比较有效。
  • Application:
  • Resource Loading:
  • Dalvik VM: 虚拟机相关信息,比如GC停顿等。
  • CPU Scheduling: CPU调度的信息;你能看到CPU在每个时间段在运行什么线程;线程调度情况,比如锁信息。

 

二、使用和分析

2.1 Device Monitor by selecting Tools > Android > Monitor.

这里写图片描述

每次抓取前,最好清理一下

2.2 绿色、黄色、红色来区分当前界面的性能等级分别是优、良、差。当遇到红色的时候肯定当前的性能需要优化。

抓取的Trace报告提供了Android系统进程在特定时间段内的整体情况。 例如在显示Activity或动画时卡顿,Systrace会提供关于如何解决这些问题的建议。
但是,systrace不会在应用程序进程中收集有关代码执行的信息

在运行Android 5.0(API级别21)或更高版本的设备上, UI 渲染的工作主要由UI ThreadRenderThread两个线程完成。

在之前的版本中,创建渲染框架的所有工作都是在UI Thread上完成的。

找到分析进程对应的ui线程,线程的纵向信息记录的是调用关系,横向信息记录的是调用顺序

obtainView ---> inflate--- Te

 

三、添加 tag 分析

从Android 4.3( 18)开始,使用Trace类,可以在代码中添加更加详细的标记。使用Trace.beginSection(String)开始一段追踪,使用Trace.endSection()结束最近的一次追踪。

 app层 自定义 TAG


import Android.os.Trace;

Trace.beginSection(String sectionName)�
... ...
Trace.EndSection() 

 Framework 层自定义 TAG


import Android.os.Trace; 

Trace.traceBegin(long traceTag, String methodName)
... ...
Trace.traceEnd(long traceTag)

. Native 层自定义 TAG


#include<utils/Trace.h> 
ATRACE_BEGIN("TEST");
... ...
ATRACE_END();

 

Systrace无法帮你定位到代码里面的具体到某一行代码,但是我们可以通过Alerts和Frames来能基本上优化了不足的地方,然后我们可以根据TraceView来分析具体函数花了多长时间来进一步优化代码提高性能。

 

Alerts和Frames两栏

这个警告指出了,有一个View#draw()方法执行了比较长的时间。我们可以在下面看到问题的描述、链接,甚至是相关的视频。

下面我们看Frames这一行,可以看到这里展示了被绘制出来的每一帧,并且用绿、黄、红三颜色来区分它们在绘制时的性能。我们选一个红色帧来瞅瞅:

在最下方,我们看到了与这一帧所相关的一些警告。

在这三个警告中,有一个是我们上面所提到的(View#draw())。接下来我们在这一帧处放大并在下方展开“Inflation during ListView recycling”这条警告:

我们可以看到警告部分的总耗时32毫秒,远高于了我们对保障60fps所需的16.6毫秒绘制时间。同时还有更多的ListView每个条目的绘制时间,大约是6毫秒每个条目,总共五个。而Description描述项中的内容会帮助我们理解问题,甚至提供问题的解决方案。回到我们上一张图片,我们可以在“inflate”这一个块区处放大,并且观察到底是哪些View在被填充过程中耗时比较严重。

 

下面是另外一个渲染过慢的实例:

在选择了某一帧之后,我们可以按“m”键来高亮这一帧,并且在上方看到了这一部分的耗时,如图,我们看到了这一阵的绘制总共耗时大约19毫秒。而当我们展开这一帧唯一的一个警告时,我们发现了“Scheduling delay”这条错误。

Scheduling delay(调度延迟)的意思就是一个线程在处理一块运算的时候,在很长一段时间都没有被分配到CPU上面做运算,从而导致这个线程在很长一段时间都没有完成工作。我们选择这一帧中最长的一块,从而得到更加详细的信息:

 

在红框区域内,我们看到了“Wall duration”,他代表着这一区块的开始到结束的耗时。之所以叫作“Wall duration”,是因为他就像是墙上的一个时钟,从线程的一开始就为你计时。

而CPU Duration一项中显示了实际CPU在处理这一区块所消耗的时间。

很显然,两个时间的差距还是非常大的。整个区块耗时18毫秒,而在这之中CPU只消耗了4毫秒的时间去运算。这就有点奇怪了,所以我们应该看一下在这整个过程之中,CPU去干吗了。

可以看到,所有四个线程都非常的繁忙。

选择其中的一个线程会告诉我们是哪个程序在占用他,在这里是一个包名为com.udinic.keepbusyapp的程序。在这里,由于另外一个程序占用CPU,导致了我们的程序未能获得足够的CPU资源。

但是这种情况其实是暂时的,因为被其他后台应用占用CPU的情况并不多见,但仍有其他应用的线程或是主线程占用CPU。而Systrace也只能为我们提供一个概览,他的深度是有限的。所以要找到我们app中到底是什么让我们的CPU繁忙,我们还要借助另一个工具——Traceview。

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值