简介
Android Profile CPU是Android studio自带的一个功能,打开方式:View > Tool Windows > Android Profiler。
用以分析应用程序进程中的每个线程在一段时间内执行哪些方法以及每个方法在执行期间消耗的CPU资源并记录其堆栈。
如何生成.trace文件
代码添加
- 用Debug.startMethodTracing和Debug.stopMethodTracing()包裹需要分析的代码。
...
Debug.startMethodTracing("test");
setContentView(R.layout.activity_main);
for (int i = 0; i < 100; i++) {
TestManager.getInstance().test("haha"+i);
}
Debug.stopMethodTracing();
...
- 使用
adb pull /sdcard/test.trace
将文件导出到电脑,然后使用Android Profiler 加载。
实时监测
打开Profiler -> CPU -> 点击 Record -> 点击 Stop -> 查看Profiler下方Top Down/Bottom Up 区域找出耗时的热点方法。
如何分析
Call Chart 、Flame Chart、Top Down与Bottom Up
Call Chart
Call Chart选项卡提供一个方法跟踪的图形表示,其中一个方法调用(或调用者)的周期和时间在水平轴上表示,而它的callees则显示在垂直轴上。对系统api的方法调用以橙色显示,调用您的应用程序自己的方法以绿色显示,方法调用第三方api(包括java语言api)以蓝色显示。下面的图显示了一个示例调用图,并说明了给定方法的自时间、子时间和总时间的概念。关于如何使用自上而下和自下而上检查痕迹的部分,请继续看下去
提示: 如果想要跳转到方法的源代码,请右键单击该方法,然后选择Jump to Source。这可以从任何窗格选项卡工作。
Flame Chart
火焰图选项卡提供了一个反向调用图表,聚合了相同的调用堆栈。也就是说,收集相同的调用序列的相同方法被收集并表示为火焰图中的一个较长的栏(而不是将它们显示为多个更短的条,如调用图所示)。这样就更容易看出哪些方法消耗的时间最多。然而,这也意味着横轴不再表示时间轴,相反,它表示每个方法执行的相对时间。
为了帮助说明这个概念,考虑下面图中的调用图表。注意,方法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)。
聚合方法调用用于创建flame 图,如下图所示。注意,对于任何给定的方法调用,在flame图中,消耗最多CPU时间的callees首先出现。
Top Down
Top Down选项卡显示方法调用的列表,扩展方法节点显示其callees。下图显示了上面的图3中调用图的顶部向下图。图中的每个箭头都是从调用者到callee。
下图所示,在顶部的down选项卡中扩展方法A的节点将显示它的callees、方法B和D。在此之后,扩展方法D的节点将暴露它的callees、方法B和C,等等。与火焰图选项卡类似,顶部向下的树聚合跟踪信息,用于共享相同调用堆栈的相同方法。也就是说,火焰图标签提供了顶部下标签的图形表示。
Top Down选项卡提供以下信息,以帮助描述在每个方法调用上花费的CPU时间(在选定的时间段内,时间也代表线程总时间的百分比):
- Self:方法调用用于执行自己的代码而不是它的callees的时间量,如上面的图所示。
- Children:方法调用花费的时间用于执行其被调用者,而不是其自己的代码,如图中的方法D所示。
- Total:方法的Self和Children的时间的总和。这表示应用程序执行方法调用的总时间量,如图所示的方法D。
Bottom Up
Bottom Up选项卡显示一个方法调用列表,扩展方法的节点显示其调用者。使用上图所示的例子中,下图提供了一个自下而上方法C .在自下而上的树中打开方法C的节点,显示每个独特的调用者,方法B和d .注意,虽然B两次调用C,B当扩大节点只出现一次自下而上方法C的树。再此之后,展开节点B显示其调用者方法A和D.
Bottom Up选项卡对于那些消耗最多(或最少)CPU时间的方法的排序方法很有用。您可以检查每个节点,以确定哪些调用者在调用这些方法上花费最多的CPU时间。与上面的树相比,底部树中每个方法的定时信息都是在每棵树的顶部(顶部节点)的方法。在记录期间,CPU时间也被表示为线程总时间的百分比。下表有助于解释如何解释顶级节点及其调用方方法(子节点)的定时信息。
Wall clock time与Thread time
Wall clock time: 表示实际经过时间。
Thread time:计时信息表示实际的消耗时间减去不消耗CPU资源的那段时间的任何部分。对于任何给定的方法,它的线程时间总是小于或等于它的时钟时间。使用线程时间让您更好地了解给定方法所消耗的线程实际CPU使用量。