一、TraceView
TraceView 是 Android SDK 自带的工具,用来分析函数调用过程,可以对Android的应用程序以及Framework层的代码进行性能分析。它是一个图形化的工具,最终会产生一个图表,用于对性能分析进行说明,可以分析到应用具体每一个方法的执行时间,使用非常直观简单,分析性能问题很简便。
- 图形的形式展示执行时间、调用栈等。
- 信息全面,包含所有线程
TraceView 使用方法
使用代码的方式生成 trace 文件。
//开始 trace 文件,保存到 sdcard/Android/data/packagename/files
Debug.startMethodTracing("PerformanceApp")
//结束
Debug.stopMethodTracing()
当你调用开始代码的时候,系统会生产 trace 文件,并且产生追踪数据,当你调用结束代码时,会将追踪数据写入到 trace 文件中。
如,在Application 中记录三方库运行情况分析,如下代码所示:
class PerformanceApp : Application() {
override fun onCreate() {
super.onCreate()
Debug.startMethodTracing("PerformanceApp")
sApplication = this
//腾讯Bugly
initBugly()
//友盟
initUmeng()
//Fresco 图片加载
initFresco()
//高德地图
initMap()
Debug.stopMethodTracing()
}
}
点击 AndroidStudio 右下角 Device File Explorer
即可打开文件位置,如下图所示。
接下来,我们打开 PerformanceApp.trace 文件,如下图:
选择时间范围: 用于确定您要在跟踪窗格中检查所记录时间范围的哪一部分。 当您首次记录函数跟踪时,CPU Profiler 将在 CPU 时间线中自动选择您的记录的完整长度。 如果您想仅检查所记录时间范围一小部分的函数跟踪数据,您可以点击并拖动突出显示的区域边缘以修改其长度。
Call Chart:调用图表
Call Chart 是 Traceview 默认使用的展示方式。它按照应用程序的函数执行顺序来展示,适合用于分析整个流程的调用。举一个最简单的例子,A 函数调用 B 函数,B 函数调用 C 函数,循环三次,就得到了 Call Chart
橙色:系统 api 调用颜色是橙色
绿色:应用自身的一些函数的调用是绿色
蓝色:第三方 api 调用是蓝色
- Flame Chart:火焰图
收集相同的调用顺序的完全相同的函数。
- Top Down 树
函数的调用列表。调用了A函数,整体时间是Total,A函数执行了一行代码,然后调用了B函数,Self 就是执行一行代码的时间,Children 就是B函数的时间。Total=Self+Children。
- Bottom Up 树
- 下拉菜单中选择如何测量每个函数调用的时间信息:
Wall clock time:壁钟时间信息表示实际经过的时间(如:一段代码发生在 A 线程上,这个线程真正执行了多长时间,比如这段代码执行了 100ms,那么 WallClockTime 就是 100ms。)
Thread time:CPU 执行的时间。线程时间信息表示实际经过的时间减去线程没有消耗 CPU 资源的任意时间部分。 对于任何给定函数,其线程时间始终少于或等于其壁钟时间。 使用线程时间可以让您更好地了解线程的实际 CPU 使用率中有多少是给定函数消耗的。
使用 Call Chart 标签检查跟踪
Call Chart 标签提供函数跟踪的图形表示形式,其中,水平轴表示函数调用(或调用方)的时间段和时间,并沿垂直轴显示其被调用者。 对系统 API 的函数调用显示为橙色,对应用自有函数的调用显示为绿色,对第三方 API(包括 Java 语言 API)的函数调用显示为蓝色。 下面的图 1 展示了一个调用图表示例,并描绘了给定函数的 self time、children time 以及总时间的概念。 您可以在如何使用 Top Down 和 Bottom Up 检查跟踪部分详细了解这些概念。
![图 1. 一个调用图表示例,描绘了函数 D 的 self、children 及总时间]
(https://upload-images.jianshu.io/upload_images/2079881-90eeb40ac0f1f84d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
使用 Flame Chart 标签检查跟踪
Flame Chart 标签提供一个倒置的调用图表,其汇总相同的调用堆栈。 即,收集共享相同调用方顺序的完全相同的函数,并在火焰图中用一个较长的横条表示它们(而不是将它们显示为多个较短的横条,如调用图表中所示)。 这样更方便您查看哪些函数消耗最多时间。 不过,这也意味着水平轴不再代表时间线,相反,它表示每个函数相对的执行时间。
为帮助说明此概念,请考虑以下图 2 中的调用图表。 请注意,函数 D 多次调用 B(B1、B2 和 B3),其中一些对 B 的调用也调用了 C(C1 和 C3)。
由于 B1、B2 和 B3 共享相同的调用方顺序 (A → D → B),因此,可将它们汇总在一起,如下所示。 同样,将 C1 和 C3 汇总在一起,因为它们也共享相同的调用方顺序 (A → D → B → C)—请注意,未包含 C2,因为它具有不同的调用方顺序 (A → D → C)。
汇总的函数调用用于创建火焰图,如图 4 所示。请注意,对于火焰图中任何给定的函数调用,消耗最多 CPU 时间的被调用方首先显示。
TraceView 缺点
TraceView 性能开销过大,有时无法反映真实的情况。比如一个函数本身的耗时是 1 秒,开启 Traceview 后可能会变成 5 秒,而且这些函数的耗时变化并不是成比例放大。
在 Android 5.0 之后,新增了startMethodTracingSampling
方法,可以使用基于样本的方式进行分析,以减少分析对运行时的性能影响。新增了 sample 类型后,就需要我们在开销和信息丰富度之间做好权衡。
本文参考:https://www.jianshu.com/p/41fcf5b4b5eb