Android 性能优化 之 TraceView工具的使用
2016-11-15 15:14
537 查看
Traceview简介
TraceView 是 Android 平台特有的数据采集和分析工具,它主要用于分析 Android 中应用程序的 hotspot。TraceView 本身只是一个数据分析工具,而数据的采集则需要使用 Android SDK 中的 Debug 类或者利用 DDMS 工具。二者的用法如下:
开发者在一些关键代码段开始前调用 Android SDK 中 Debug 类的 startMethodTracing 函数,并在关键代码段结束前调用 stopMethodTracing 函数。这两个函数运行过程中将采集运行时间内该应用所有线程(注意,只能是 Java 线程)的函数执行情况,并将采集数据保存到 /mnt/sdcard/ 下的一个文件中。开发者然后需要利用 SDK 中的 TraceView 工具来分析这些数据。
借助 Android SDK 中的 DDMS 工具。DDMS 可采集系统中某个正在运行的进程的函数调用信息。对开发者而言,此方法适用于没有目标应用源代码的情况。
DDMS 中 TraceView 使用示意图如下,调试人员可以通过选择 Devices 中的
![](https://img-blog.csdn.net/20161115134331300)
应用后点击 按钮 Start Method Profiling(开启方法分析)和点击
![](https://img-blog.csdn.net/20161115134438782)
Stop Method Profiling(停止方法分析)
![](https://img-blog.csdn.net/20161115134512316)
我这边用一个简单的demo学习一下这个工具的使用。
代码如下所示:
这个demo主要功能是每两秒随机显示一张广告图片。首先将三张图片资源引用ID保存到 path 这个数组中。
MainActivity 重写 Runnable的 Run函数,每隔两秒钟随机发送一个图片ID给hander然后显示。
我们在显示广告图片中故意加一个循环用于延迟广告图片显示。
其UI划分为上下两个面板,即Timeline Panel(时间线面板)和Profile Panel(分析面板)。
![](https://img-blog.csdn.net/20161115150304303)
左边Pane显示的是测试数据中所采集的线程信息。由图1-4可知,本次测试数据采集了main线程,两个Binder线程和其它系统辅助线程(例如GC线程等)的信息。
右边Pane所示为时间线,时间线上是每个线程测试时间段内所涉及的函数调用信息。这些信息包括函数名、函数执行时间等。由图可知,main线程对应行的的内容非常丰富,而其他线程在这段时间内干得工作则要少得多。
另外,开发者可以在时间线Pane中移动时间线纵轴。纵轴上边将显示当前时间点中某线程正在执行的函数信息。
同意颜色在实际轴越长说明该颜色代表的函数花费时间越长
Profile Panel 是 TraceView 的核心界面,其内涵非常丰富。它主要展示了某个线程(先在 Timeline Panel 中选择线程)中各个函数调用的情况,包括 CPU 使用时间、调用次数等信息。而这些信息正是查找 hotspot 的关键依据。所以,对开发者而言,一定要了解 Profile Panel 中各列的含义。下表列出了 Profile Panel 中比较重要的列名及其描述。
![](https://img-blog.csdn.net/20161115153318443)
另外,每一个Time列还对应有一个用时间百分比来统计的列(如Incl Cpu Time列对应还有一个列名为Incl Cpu Time %的列,表示以时间百分比来统计的Incl Cpu Time)。
了解完Traceview的UI后,现在介绍如何利用Traceview来查找hotspot。
一般而言,hotspot包括两种类型的函数:
一类是调用次数不多,但每次调用却需要花费很长时间的函数。在示例代码中,它就是hotspot 1。
一类是那些自身占用时间不长,但调用却非常频繁的函数。在示例代码中,它就是hotspot 2。
在我们代码中handleMessage 函数属于 每次调用花费很长时间的函数。因为里面有个耗时的dynatest循环在那一直处理。
![](https://img-blog.csdn.net/20161115161032520)
从上图中我们可以发现
标号 12 的 com.mingrisoft.MainActivity.dynatest这一行很特别。它的Incl Cpu Time % 是 32.1 % ,Excl Cpu Time 也是 32.1% ,并且 它的 Calls+Recur Calls/Total列显示其调用次数为1,即它仅仅被调用一次了。这个函数是应用程序实现的,所以极有可能是一个潜在的Hotspot。在这个函数里面做了很多耗时的操作。
比如标号 11 的 handleMessage 虽然 它的Incl Cpu Time % 是 40.2 %,但是它的Excl Cpu Time 是 0 % 。
说明dynatest可能是手机发烫、卡顿、高 CPU 占用率的原因所在。
我们现在把函数 dynatest() 注释掉,再看看结果:
![](https://img-blog.csdn.net/20161115164902994)
![](https://img-blog.csdn.net/20161115165155808)
说明去掉dynatest这个函数后。handleMessage 主要花费时间都是在 setImageResource 函数上。而且这个函数是系统函数。
第二种情况:
就是虽然每次调用花费时间不是很多。但是调用次数很多的那种情况。
源码中函数dynatest() 注释掉。添加一下代码
然后运行TraceView得到下面的图:
![](https://img-blog.csdn.net/20161116102917156)
![](https://img-blog.csdn.net/20161116103350987)
发现这三个类的Incl Cpu Time 很高分别是55.6% 10.6% 和7.6%,但是你有发现他们每次的Incl Real Time大约分部是
![](https://img-blog.csdn.net/20161116103717707)
1535 282 和 198.每次占用cpu时间很短。但是占用整个cpu运行周期的比例确实很高。这说明只有一种情况。这几个函数执行频率非常高。通过查看Call+Recur Calls/Total 发现情侣确实如我所料。
![](https://img-blog.csdn.net/20161116104111162)
这里发现执行次数达到49947.而且函数大部分都是一次。这说明这几个函数运行次数太多。可以在实际开发过程中优化
TraceView 是 Android 平台特有的数据采集和分析工具,它主要用于分析 Android 中应用程序的 hotspot。TraceView 本身只是一个数据分析工具,而数据的采集则需要使用 Android SDK 中的 Debug 类或者利用 DDMS 工具。二者的用法如下:
开发者在一些关键代码段开始前调用 Android SDK 中 Debug 类的 startMethodTracing 函数,并在关键代码段结束前调用 stopMethodTracing 函数。这两个函数运行过程中将采集运行时间内该应用所有线程(注意,只能是 Java 线程)的函数执行情况,并将采集数据保存到 /mnt/sdcard/ 下的一个文件中。开发者然后需要利用 SDK 中的 TraceView 工具来分析这些数据。
借助 Android SDK 中的 DDMS 工具。DDMS 可采集系统中某个正在运行的进程的函数调用信息。对开发者而言,此方法适用于没有目标应用源代码的情况。
DDMS 中 TraceView 使用示意图如下,调试人员可以通过选择 Devices 中的
应用后点击 按钮 Start Method Profiling(开启方法分析)和点击
Stop Method Profiling(停止方法分析)
我这边用一个简单的demo学习一下这个工具的使用。
代码如下所示:
package com.mingrisoft; import java.util.ArrayList; import java.util.List; import java.util.Random; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.ImageView; import android.widget.TextView; public class MainActivity extends Activity implements Runnable { private ImageView iv; // 声明一个显示广告图片的ImageView对象 private Handler handler; // 声明一个Handler对象 private List<Integer> list1 = new ArrayList<Integer>(); private int[] path = new int[] { R.drawable.img01, R.drawable.img02, R.drawable.img03, R.drawable.img04, R.drawable.img05, R.drawable.img06 }; // 保存广告图片的数组 private String[] title = new String[] { "编程词典系列产品", "高效开发", "快乐分享", "用户人群", "快速学习", "全方位查询" }; // 保存显示标题的数组 public void dynatest() { for(int i = 0; i < 500000; i++) { //Log.i(TAG, "======== "); list1.add(i); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); iv = (ImageView) findViewById(R.id.imageView1); // 获取显示广告图片的ImageView Thread t = new Thread(this); // 创建新线程 t.start(); // 开启线程 // 实例化一个Handler对象 handler = new Handler() { @Override public void handleMessage(Message msg) { // 更新UI TextView tv = (TextView) findViewById(R.id.textView1); // 获取TextView组件 if (msg.what == 0x101) { dynatest(); tv.setText(msg.getData().getString("title")); // 设置标题 iv.setImageResource(path[msg.arg1]); // 设置要显示的图片 } super.handleMessage(msg); } }; } @Override public void run() { int index = 0; while (!Thread.currentThread().isInterrupted()) { index = new Random().nextInt(path.length); // 产生一个随机数 Message m = handler.obtainMessage(); // 获取一个Message m.arg1 = index; // 保存要显示广告图片的索引值 Bundle bundle = new Bundle(); // 获取Bundle对象 m.what = 0x101; // 设置消息标识 bundle.putString("title", title[index]); // 保存标题 m.setData(bundle); // 将Bundle对象保存到Message中 handler.sendMessage(m); // 发送消息 try { Thread.sleep(2000); // 线程休眠2秒钟 } catch (InterruptedException e) { e.printStackTrace(); // 输出异常信息 } } } }
这个demo主要功能是每两秒随机显示一张广告图片。首先将三张图片资源引用ID保存到 path 这个数组中。
private int[] path = new int[] { R.drawable.img01, R.drawable.img02, R.drawable.img03, R.drawable.img04, R.drawable.img05, R.drawable.img06 }; // 保存广告图片的数组
MainActivity 重写 Runnable的 Run函数,每隔两秒钟随机发送一个图片ID给hander然后显示。
TextView tv = (TextView) findViewById(R.id.textView1); // 获取TextView组件 if (msg.what == 0x101) { //故意增加延迟 for(int i = 0; i < 10000; i++) { list1.add(i); } tv.setText(msg.getData().getString("title")); // 设置标题 iv.setImageResource(path[msg.arg1]); // 设置要显示的图片 }
我们在显示广告图片中故意加一个循环用于延迟广告图片显示。
其UI划分为上下两个面板,即Timeline Panel(时间线面板)和Profile Panel(分析面板)。
左边Pane显示的是测试数据中所采集的线程信息。由图1-4可知,本次测试数据采集了main线程,两个Binder线程和其它系统辅助线程(例如GC线程等)的信息。
右边Pane所示为时间线,时间线上是每个线程测试时间段内所涉及的函数调用信息。这些信息包括函数名、函数执行时间等。由图可知,main线程对应行的的内容非常丰富,而其他线程在这段时间内干得工作则要少得多。
另外,开发者可以在时间线Pane中移动时间线纵轴。纵轴上边将显示当前时间点中某线程正在执行的函数信息。
同意颜色在实际轴越长说明该颜色代表的函数花费时间越长
Profile Panel 是 TraceView 的核心界面,其内涵非常丰富。它主要展示了某个线程(先在 Timeline Panel 中选择线程)中各个函数调用的情况,包括 CPU 使用时间、调用次数等信息。而这些信息正是查找 hotspot 的关键依据。所以,对开发者而言,一定要了解 Profile Panel 中各列的含义。下表列出了 Profile Panel 中比较重要的列名及其描述。
另外,每一个Time列还对应有一个用时间百分比来统计的列(如Incl Cpu Time列对应还有一个列名为Incl Cpu Time %的列,表示以时间百分比来统计的Incl Cpu Time)。
了解完Traceview的UI后,现在介绍如何利用Traceview来查找hotspot。
一般而言,hotspot包括两种类型的函数:
一类是调用次数不多,但每次调用却需要花费很长时间的函数。在示例代码中,它就是hotspot 1。
一类是那些自身占用时间不长,但调用却非常频繁的函数。在示例代码中,它就是hotspot 2。
在我们代码中handleMessage 函数属于 每次调用花费很长时间的函数。因为里面有个耗时的dynatest循环在那一直处理。
从上图中我们可以发现
标号 12 的 com.mingrisoft.MainActivity.dynatest这一行很特别。它的Incl Cpu Time % 是 32.1 % ,Excl Cpu Time 也是 32.1% ,并且 它的 Calls+Recur Calls/Total列显示其调用次数为1,即它仅仅被调用一次了。这个函数是应用程序实现的,所以极有可能是一个潜在的Hotspot。在这个函数里面做了很多耗时的操作。
比如标号 11 的 handleMessage 虽然 它的Incl Cpu Time % 是 40.2 %,但是它的Excl Cpu Time 是 0 % 。
说明dynatest可能是手机发烫、卡顿、高 CPU 占用率的原因所在。
我们现在把函数 dynatest() 注释掉,再看看结果:
说明去掉dynatest这个函数后。handleMessage 主要花费时间都是在 setImageResource 函数上。而且这个函数是系统函数。
第二种情况:
就是虽然每次调用花费时间不是很多。但是调用次数很多的那种情况。
源码中函数dynatest() 注释掉。添加一下代码
public void handleMessage(Message msg) { // 更新UI TextView tv = (TextView) findViewById(R.id.textView1); // 获取TextView组件 if (msg.what == 0x101) { //dynatest() ; for(int i = 0; i < 500000; i++) { //Log.i(TAG, "======== "); list1.add(i); } tv.setText(msg.getData().getString("title")); // 设置标题 iv.setImageResource(path[msg.arg1]); // 设置要显示的图片 }
然后运行TraceView得到下面的图:
发现这三个类的Incl Cpu Time 很高分别是55.6% 10.6% 和7.6%,但是你有发现他们每次的Incl Real Time大约分部是
1535 282 和 198.每次占用cpu时间很短。但是占用整个cpu运行周期的比例确实很高。这说明只有一种情况。这几个函数执行频率非常高。通过查看Call+Recur Calls/Total 发现情侣确实如我所料。
这里发现执行次数达到49947.而且函数大部分都是一次。这说明这几个函数运行次数太多。可以在实际开发过程中优化
相关文章推荐
- Android 性能优化 二 TraceView工具的使用
- Android 性能优化 二 TraceView工具的使用
- Android 性能优化 TraceView工具的使用
- Android 性能优化 二 TraceView工具的使用
- Android 中性能优化工具之TraceView使用总结
- Android 性能优化 二 TraceView工具的使用
- Android 性能优化 二 TraceView工具的使用
- Android 性能优化 二 TraceView工具的使用
- Android 性能优化 二 TraceView工具的使用
- Android 性能优化 五 性能分析工具dumpsys的使用
- Android的ExpandableListView的动画展开效果和使用traceview的性能优化
- android TraceView (图形化性能测试工具)使用入门笔记
- android TraceView使用以及listview 的性能优化测试(一) .
- 正确使用Android性能分析工具——TraceView
- Android 性能优化工具 Traceview和dmtracedump
- [转载]正确使用Android性能分析工具——TraceView
- android TraceView使用以及listview 的性能优化测试(一)
- 正确使用Android性能分析工具——TraceView
- 正确使用Android性能分析工具——TraceView
- 正确使用Android性能分析工具——TraceView