1. TraceView 简介
TraceView 是 Android 平台配备一个很好的性能分析的工具。它主要用于分析 Android 中应用程序的 hotspot,它可以通过图形化的方式让我们了解我们要跟踪的程序的性能,并且能具体到 method。详细内容参考:Profiling with Traceview and dmtracedump
2. TraceView 的使用
使用 TraceView 主要有两种方式:
没有目标应用源码的情况下,可以使用
DDMS来进行数据的采集。具体的步骤:- 选择需要分析的进程
- 点击
DDMS界面中的Start Method Profiling按钮,等红色的小点变成黑色之后就表示TraceView已经开始工作了。然后就可以进行应用的操作了,操作最好不要超过 5 秒,因为最好是进行小范围的性能测试。然后再点击一次Stop Method Profiling按钮,则会出现另外一个界面。
在有源码的情况下, 在源码中使用
android.os.Debug.startMethodTracing()和android.os.Debug.stopMethodTracing()方法。当运行这两个方法之间的代码时就会有一个trace文件在/sdcard目录中生成。也可以通过startMethodTracing(String traceName)设置trace文件的文件名,最后可以通过adb pull /sdcard/xxx.trace /tmp命令将trace文件拉取到电脑中,然后使用DDMS工具进行分析。使用
DDMS的方法适用范围更广,但是使用startMethodProfiling()的方法更加精确一些。
3. TraceView 界面
整个 TraceView 如上图所示,其中需要注意的地方如图标识:
- 被监控应用的进程名
Start Method Profiling,Stop Method Profiling按钮- 测试进程中每个线程的执行情况,每个线程占一行
- 时间轴
- 显示当前选中的方法
当选择某个方法之后(比如:Handler.dispatchMessage())会显示两部分数据:
Parents: 表示调用Handler.dispatchMessage()方法的父方法,可以看到方法编号为 0Children: 表示Handler.dispatchMessage()方法内部调用的其他方法,可以看到它调用了三个方法
traceView的指标参数列,详细列出了每个方法的 CPU 使用时间,调用次数等,这些信息是查找hotspot的关键。|列名|描述|
|:–|:–|
|Name|该线程运行过程中所调用的方法名|
|Incl Cpu Time|某方法占用的 CPU 时间,包含内部调用其他方法的 CPU 时间|
|Excl CPU Time|某方法占用的 CPU 时间,但是不包含内部调用其他方法的 CPU 时间|
|Incl Real Time|某方法运行的真实时间(以毫秒为单位),包含调用其他方法所占用的真实时间|
|Excl Real Time|某方法运行的真实时间(以毫秒为单位),但是不包含调用其他方法所占用的真实时间|
|Call+RecurCalls/Total|某方法被调用次数以及递归调用的次数|
|Cpu Time/Call|某方法调用 CPU 时间与调用次数的比,也就是该方法平均执行时间|
|Real Time/Call|某方法真实的平均执行时间|
4. TraceView 实战
了解完 TraceView 的界面后,现在介绍如何利用 TraceView 来查找 hotspot。一般而言,hotspot 包括两种类型的函数:
- 一类是调用次数不多,但每次调用却需要花费很长时间的函数。
- 一类是那些自身占用时间不长,但调用却非常频繁的函数。
这里主要使用 Android application (performance and more) analysis tools - Tutorial 提供的示例来进行练习。
我的结果分析步骤如下:
- 按照
Incl Cpu Time进行降序排列 从 Top1 的方法开始,逐层的进入它的
Children方法,判断的标准是 别调用方法的Incl Cpu Time占调用方法的百分比。比如上图中
Handler.dispatchMessage()的Children中,调用Handler.handleCallback()方法占据了 99.8% 的比例,所以下一步就进入到Handler.handleCallback()方法进行进一步的分析这样一层层的分析,直到找到我们监控的应用的方法,然后再详细查看该方法具体在那块存在性能问题。
以上述
demo为例,应用的包名为csmijo.com.traceviewdemo。 一层层分析后发现在csmijo/com/traceviewdemo/MyArrayAdapter.getView()方法中出现问题,而该方法主要的CPU消耗用在标识的三个方法的调用中,所以就需要在相应的代码处查看并进行优化。
以上是我个人学习使用 TraceView 的经验,尤其实战部分,仅供参考,如果有任何错误的地方,请帮忙指正,谢谢。
[参考文献]