关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
专注于分享各领域原创系列文章 ,擅长java后端、移动开发、人工智能等,希望大家多多支持。
目录
- 一、导读
- 二、概览
- 三、使用
-
- [3.1 通过调用系统API](#3.1 通过调用系统API)
- [3.2 通过Android Studio](#3.2 通过Android Studio)
-
- [3.2.1 轨迹界面说明](#3.2.1 轨迹界面说明)
- [3.2.2 Android Studio 抓取 App 启动的 trace 信息](#3.2.2 Android Studio 抓取 App 启动的 trace 信息)
- 四、trace文件分析
-
- [4.1 使用调用图表检查跟踪数据](#4.1 使用调用图表检查跟踪数据)
- [4.2 Flame Chart](#4.2 Flame Chart)
- [4.3 Top Down](#4.3 Top Down)
- [4.4 Bottom Up](#4.4 Bottom Up)
- [4.5 Events](#4.5 Events)
- 五、优缺点
- 六、推荐阅读
一、导读
我们继续总结学习Android基础知识 ,温故知新。
工欲善其事必先利其器,我们要做性能优化,首先要掌握好相关工具。
二、概览
Traceview 是一个用于分析应用程序性能的工具,用来分析函数调用过程。
CPU Profiler 是 集成在Android Studio 3.2版本之后的Android Profiler工具当中,实时记录展示 App cpu消耗,用来替代Traceview。
都可以记录应用程序在运行过程中的各个方法(函数)的执行时间 以及方法之间的调用关系。通过Traceview,开发者可以了解应用程序中哪些方法占用了较多的时间,从而找到性能瓶颈并进行优化。
还可以以图形方式显示方法的调用树,使开发者能够更直观地分析代码的执行流程。
常用于卡顿优化、启动优化、内存优化等。
这里我们要了解一下traceview 跟 cpu profile的区别,我们在新版的android studio中已经没有单独的traceview了,就是换成cpu profile,一样的。
三、使用
我们可以有两种方式来抓取相关信息。
3.1 通过调用系统API
java
开始:
Debug.startMethodTracingSampling(new File("ddd"), 0, 5000);
这样的话,我们就开始通过traceview来使用
结束:
Debug.stopMethodTracing();
当调用该方法后,就会生产一个文件,
当文件生成后,存放位置 sd卡/Android/data/包名/files 目录下,
startMethodTracingSampling 是有几个重载的方法的,我们看下源码
java
/**
*
* tracePath -- 文件名,或者传入具体的路径
* bufferSize -- 文件大小,默认8MB.
* intervalUs -- The amount of time between each sample in microseconds.
*/
startMethodTracingSampling(String tracePath, int bufferSize, int intervalUs) {
VMDebug.startMethodTracing(fixTracePath(tracePath), bufferSize, 0, true, intervalUs);
}
3.2 通过Android Studio
如下图所示,依次点击profile - cpu ,然后会跳转到 cpu界面,然后就可以进行录制了。
通过图2,我们可以看到这里有四个选项,我们分别介绍: 官网
-
Callstack Sample (Sample C/C++ Functions)
捕获应用的原生线程的采样跟踪数据。在内部,此配置使用 simpleperf 跟踪应用的原生代码。
-
System Trace (Trace System Calls:)
捕获非常翔实的细节,以便您检查应用与系统资源的交互情况。您可以检查线程状态的确切时间和持续时间、直观地查看所有内核的CPU瓶颈在何处,并添加需分析的自定义跟踪事件。
-
Java/Kotlin Method Trace (Trace Java Methods)
在运行时检测应用,从而在每个方法调用开始和结束时记录一个时间戳。系统会收集并比较这些时间戳,以生成方法跟踪数据,包括时间信息和 CPU 使用率。
请注意,与检测每个方法相关的开销会影响运行时性能,并且可能会影响分析数据;对于生命周期相对较短的方法,这一点更为明显。此外,如果应用在短时间内执行大量方法,则分析器可能很快就会超出其文件大小限制,因而不能再记录更多跟踪数据。
-
Java/Kotlin Method Sample (Sample Java Methods )
在应用的 Java 代码执行期间,频繁捕获应用的调用堆栈。分析器会比较捕获的数据集,以推导与应用的 Java 代码执行有关的时间和资源使用信息。
基于采样的跟踪存在一个固有的问题,那就是如果应用在捕获调用堆栈后进入一个方法并在下次捕获前退出该方法,分析器将不会记录该方法调用。如果您想要跟踪生命周期如此短的方法,应使用插桩跟踪。
点击record开始记录,当应用交互,然后在完成时点击 Stop。性能分析器会自动在轨迹窗格中显示其跟踪信息,如下图所示。
3.2.1 轨迹界面说明
我们先对上图的每个区域做一下解释:
-
选定范围:确定需在轨迹窗格中检查所记录时间的哪一部分。当您首次记录轨迹时,CPU 性能分析器会自动在 CPU 时间轴上选择记录的完整长度。如需仅检查已记录的时间范围中的一部分的跟踪数据,请拖动突出显示区域的边缘。
-
"Interaction"部分:沿着时间轴显示用户互动和应用生命周期事件。
-
"Threads"部分:沿时间轴针对每一个线程显示线程状态活动(例如运行、休眠等)和调用图表(在 System Trace 中则为轨迹事件图表)。
使用鼠标和键盘快捷键在时间轴上导航。
双击线程名称,或在选中线程时按 Enter 键以展开或折叠线程。
选择某个线程即可在"Analysis"窗格中查看更多信息。 按住 Shift 或 Ctrl(Mac 上为 Command)可选择多个线程。
选择方法调用(或 System Trace 中的轨迹事件),以在"Analysis"窗格中查看更多信息。
-
"Analysis"窗格:就是标记 4 的那一片的整个区域,显示您选择的时间范围和线程/方法调用的跟踪数据。在此窗格中,您可以选择如何查看每个堆栈轨迹(使用"Analysis"标签页 ,下面第 5 个 ),以及如何测量执行时间(使用"Time reference"下拉菜单下面第 6 个)。
-
"Analysis"标签页:选择如何显示跟踪数据详细信息。如需详细了解各个选项,请参阅检查跟踪数据。
-
"Time reference"菜单:选择以下选项之一,以确定如何测量每次调用的时间信息(仅在示例/跟踪 Java 方法中受支持):
wall clock time : 程序执行时间,包括调用其他方法的时间
thread time: cpu执行时间
- 搜索框,可按函数、方法、类或软件包名称过滤跟踪数据。
3.2.2 Android Studio 抓取 App 启动的 trace 信息
如果我们要在应用一启动就记录CPU活动,需要单独配置一下:
- 依次选择 Run > Edit Configurations
- 选择 Profiling - 勾选 Start this recording on startup - 选 callstack sample(跟踪 Java 方法)- apply -ok
四、trace文件分析
不管通过那种方式,我们得到trace文件后,直接拖到 android studio里面打开即可。
CPU 性能分析器中的轨迹视图提供了多种方法查看来自所记录的轨迹的信息。
-
对于方法轨迹和函数轨迹,您可以直接在 Threads 时间轴中查看 Call Chart,并从 Analysis 窗格中查看 Flame Chart、Top Down、Bottom Up 和 Events 标签页。
-
对于调用堆栈帧,您可以查看代码中已执行的部分及其调用原因。
-
对于系统轨迹,您可以直接在 Threads 时间轴中查看 Trace Events,并从 Analysis 窗格中查看 Flame Chart、Top Down、Bottom Up 和 Events 标签页。
提示:检查 Threads 时间轴时,您可以使用以下快捷方式:
- 放大:按 W 或在按住 Ctrl 键的同时滚动鼠标滚轮(在 Mac 上,按住 Command 键)。
- 缩小:按 S 或在按住 Ctrl 键的同时向后滚动鼠标滚轮(在 Mac 上,按住 Command 键)。
- 向左平移:按 A 键或在按住空格键的同时向右拖动鼠标。
- 向右平移:按 D 键或在按住空格键的同时向左拖动鼠标。
- 展开或收起线程:双击线程名称,或在选中线程时按 Enter 键。
4.1 使用调用图表检查跟踪数据
举个例子,一个调用图表示例,展示了方法 D 的 Self 时间、Children 时间和 Total 时间。
4.2 Flame Chart
Flame Chart 标签页提供一个倒置的调用图表,用来汇总完全相同的调用堆栈 。
将具有相同调用方顺序的完全相同的方法或函数收集起来,并在火焰图中将它们表示为一个较长的横条。
这样更方便您查看哪些方法或函数消耗的时间最多。不过,这也意味着,横轴不代表时间轴,而是表示执行每个方法或函数所需的相对时间。
4.3 Top Down
用于显示方法等调用列表。
如图 所示,在 Top Down 标签页中展开方法 A 的节点会显示它的被调用方,即方法 B 和 D。在此之后,展开方法 D 的节点会显示它的被调用方,即方法 B 和 C,依此类推。
Top Down 标签提供一些信息来显示每个调用所花的 CPU 时间:
- Self:方法或函数调用在执行自己的代码(而非被调用方的代码)上所花的时间,如图 1 中的方法 D 所示。
- Children:方法或函数调用在执行它的被调用方(而非自己的代码)上所花的时间,如图 1 中的方法 D 所示。
- Total:方法的 Self 时间和 Children 时间的总和。这表示应用在执行调用时所用的总时间,如图 1 中的方法 D 所示。
4.4 Bottom Up
Bottom Up 标签页用于按照占用的 CPU 时间由多到少(或由少到多)的顺序对方法或函数排序。您可以检查每个节点以确定哪些调用方在调用这些方法或函数上所花的 CPU 时间最多。
4.5 Events
"Events"表格列出了当前所选线程中的所有调用。
五、优缺点
运行时开销严重,整个代码运行都变得非常慢,因为traceview会抓取所有线程的所有函数的数据。
所有有可能带偏我们的优化方向。
比如有个方法xyz(),本身不耗时,但是加上traceview后,我们在文件里面发现它的耗时变长了,我们可能会错误的认为这个方法很耗时,然后花费精力在这个上面。