Traceview和dmtracedump分析工具
Traceview的界面布局
- 时间线面板 ---- 描述每个线程和方法何时起止
- 分析面板 ---- 提供每个方法的情况概要
时间线面板
分析面板
Traceview文件格式
data文件格式
key文件格式
创建跟踪文件
- 在代码中,使用Debug类,调用这个类的方法来开始和结束跟踪,并将跟踪信息写入到磁盘。这种方式很精确,因为你可以在代码中精确的指定在什么位置开始和结束跟踪数据。
- 使用DDMS的方法分析特性。这种方法不那么精确,因为你没有更改代码,而只是通过DDMS指定什么时候开始和结束log。尽管这种方式,不能精确控制log的地方,但是如果你无法接触程序代码,或者不需要第一种方式那么精确时,这仍然是一种很有用的方法。
- 如果你使用Debug类,你的设备或者模拟器需要有SD卡,并且程序有写入SD卡的权限。
- 如果你使用DDMS,Android 1.5的设备是不支持的。
- 如果你使用DDMS,Android2.1或之前的设备,必须有SD卡,并且程序有写入SD卡的权限。
- 如果你使用DDMS,Android2.2或之后的设备,不需要SD卡,trace log文件直接传到了你的开发机上。
// start tracing to "/sdcard/calc.trace" Debug.startMethodTracing("calc"); // ... // stop tracing Debug.stopMethodTracing();程序调用startMethodTracing()方法,系统会创建名为.trace的log文件。这个文件包含二进制的方法跟踪数据和线程方法名称映射表。
复制跟踪文件到主机
adb pull /sdcard/calc.trace /tmp
用Traceview查看trace文件
traceview /tmp/calc注意:如果你要查看那些使用了Proguard的程序(Release模式编译)生成的log文件,一些方法和成员名称可能会被混淆。你可以使用Proguard的mapping.txt来计算出原始的未混淆的名称。关于该文件的更多信息,请查看Proguard文档。
使用dmtracdedump
- ---- 调用的参考编号,trace log中用到的。
- ---- Inclusive消耗时间(方法,包括所有child方法消耗的毫秒数)
- ---- Exclusive消耗时间(方法,不包括任何child方法消耗的毫秒数)
- ----
调用数
dmtracedump [-ho] [-s sortable] [-d trace-base-name] [-g outfile] <</span>trace-base-name>dmtracedump从 .data和 .key文件中载入trace log数据。下表列出了dmtracedump的选项。
Option | Description |
---|---|
-d |
Diff with this trace name |
-g |
Generate output to |
-h |
Turn on HTML output |
-o |
Dump the trace file instead of profiling |
-d |
URL base to the location of the sortable javascript file |
-t |
Minimum threshold for including child nodes in the graph (child's inclusive time as a percentage of parent inclusive time). If this option is not used, the default threshold is 20%. |
$ dmtracedump.exe
Copyright (C) 2006 The Android Open Source Project
usage: G:\android-sdk-windows\tools\dmtracedump.exe [-ho] [-s sortable] [-d trace-file-name] [-g outfile] trace-file-name
-d trace-file-name - Diff with this trace
-g outfile - Write graph to 'outfile'
-k - When writing a graph, keep the intermediate DOT file
-h - Turn on HTML output
-o - Dump the dmtrace file instead of profiling
-s - URL base to where the sortable javascript file
-t threshold - Threshold percentage for including nodes in the graph
Traceview的已知问题
- 如果在分析期间,线程退出,那么该线程名字不会出现。
- VM重用线程ID。如果一个线程退出,又起了另一个线程,它们的ID可能相同。
$ traceview.bat ./ddms61735.trace
The standalone version of traceview is deprecated.
Please use Android Device Monitor (tools/monitor) instead.
trace file './ddms61735.trace' not found
$ monitor.bat
大家可以看到一般一个虚拟机实例进程都包含有如下7个通用的线程,下面大致讲一下这些线程的作用和创建流程。
1. main
这个就是主线程了。具体流程待细述。
2. HeapWorker
一个异步的工作线程,处理那些需要在单独线程里面做的避免同步问题的堆操作。其源代码在dalvik/vm/alloc/HeapWorker.*部分。
3. Signal Catcher
这个线程是用来捕获linux信号和做一些后续处理的。比如说,当一个SIGQUIT (Ctrl-\)信号到达后,这个线程就会挂起虚拟机,并且将所有线程的状态信息输出到log。其源代码在dalvik/vm/SignalCatcher.*部分。
4. JDWP
这个线程是用来实现Java Debug Wire Protocol的。如果命令行调试器的参数为"suspend=y",这样会暂停虚拟机。这个估计和eclipse的调试和ddms等调试工具相关。其源代码在dalvik/vm/jdwp/*部分。
5. Stdio Converter
这个线程从标准输出和标准错误输出读取信息并将它们转换为log信息。其源代码在dalvik/vm/StdioConverter.*部分。
6. Compiler
Android's Jit独立于目标平台的部分。其源代码在dalvik/vm/compiler/Compiler.*和dalvik/vm/interp/Jit.*等部分。
7. Binder Thread #%d
使用binder进行通讯时用到的线程。其源代码在frameworks/base/libs/binder/*等部分。
以下的线程属于system_server和应用程序专有线程,视具体应用的需求而定。
8. system_server专有
android.server.ServerThread
ActivityManager
ProcessStats
PackageManager
FileObserver
AccountManagerService
SyncHandlerThread
UEventObserver
PowerManagerService
AlarmManager
WindowManager
InputDeviceReader
WindowManagerPolicy
InputDispatcher
ConnectivityThread
WifiService
WifiWatchdogThread
LocationManagerService
AudioService
GpsEventThread
GpsNetworkThread
android.hardware.SensorManager$SensorThread
watchdog
Wallpaper
com.android.server.MountListener
9. misc
其他部分线程由java层的api提供,Thread等。