blob: cfa1bb1c95aad04f43062dfd6e462d3908064422 [file] [log] [blame]
Robert Lyce4d2292010-12-16 17:26:11 -08001page.title=Profiling with Traceview and dmtracedump
2@jd:body
3
4 <div id="qv-wrapper">
5 <div id="qv">
6 <h2>In this document</h2>
7
8 <ol>
9 <li>
10 <a href="#traceviewLayout">Traceview Layout</a>
11
12 <ol>
13 <li><a href="#timelinepanel">Timeline Panel</a></li>
14
15 <li><a href="#profilepanel">Profile Panel</a></li>
16 </ol>
17 </li>
18
19 <li>
20 <a href="#format">Traceview File Format</a>
21 <ol>
22 <li><a href="#datafileformat">Data File Format</a></li>
23
24 <li><a href="#keyfileformat">Key File Format</a></li>
25 </ol>
26 </li>
27
28 <li><a href="#creatingtracefiles">Creating Trace Files</a></li>
29
30 <li><a href="#copyingfiles">Copying Trace Files to a Host Machine</a></li>
31
32 <li><a href="#runningtraceview">Viewing Trace Files in Traceview</a></li>
33
34 <li><a href="#dmtracedump">Using dmtracedump</a></li>
35
36 <li><a href="#knownissues">Traceview Known Issues</a></li>
37 </ol>
38 </div>
39 </div>
40
41 <p>Traceview is a graphical viewer for execution logs that you create by using the {@link
42 android.os.Debug} class to log tracing information in your code. Traceview can help you debug
43 your application and profile its performance.</p>
44
45 <h2 id="traceviewLayout">Traceview Layout</h2>
46
47 <p>When you have a trace log file (generated by adding tracing code to your application or by DDMS),
48 you can have Traceview load the log files and display their data in a window visualizes your application
49 in two panels:</p>
50
51 <ul>
52 <li>A <a href="#timelinepanel">timeline panel</a> -- describes when each thread and method
53 started and stopped</li>
54
55 <li>A <a href="#timelinepanel">profile panel</a> -- provides a summary of what happened inside
56 a method</li>
57 </ul>
58
59 <p>The sections below provide addition information about the traceview output panes.</p>
60
61 <h3 id="timelinepanel">Timeline Panel</h3>
62
63 <p>The image below shows a close up of the timeline panel. Each thread&rsquo;s execution is shown
64 in its own row, with time increasing to the right. Each method is shown in another color (colors
65 are reused in a round-robin fashion starting with the methods that have the most inclusive time).
66 The thin lines underneath the first row show the extent (entry to exit) of all the calls to the
67 selected method. The method in this case is <code>LoadListener.nativeFinished()</code> and it was selected in
68 the profile view.</p>
69
70 <img src="/images/traceview_timeline.png"
71 alt="Traceview timeline panel"
72 width="893"
73 height="284" />
74 <p class="img-caption"><strong>Figure 1.</strong> The Traceview Timeline Panel</p>
75
76 <h3 id="profilepanel">Profile Panel</h3>
77
78 <p>Figure 2 shows the profile pane, a summary of all the time spent
79 in a method. The table shows both the inclusive and exclusive times (as well as the percentage of
80 the total time). Exclusive time is the time spent in the method. Inclusive time is the time spent
81 in the method plus the time spent in any called functions. We refer to calling methods as
82 "parents" and called methods as "children." When a method is selected (by clicking on it), it
83 expands to show the parents and children. Parents are shown with a purple background and children
84 with a yellow background. The last column in the table shows the number of calls to this method
85 plus the number of recursive calls. The last column shows the number of calls out of the total
86 number of calls made to that method. In this view, we can see that there were 14 calls to
87 <code>LoadListener.nativeFinished();</code> looking at the timeline panel shows that one of those calls took
88 an unusually long time.</p>
89
90 <img src="/images/traceview_profile.png"
91 alt="Traceview profile panel."
92 width="892"
93 height="630" />
94 <p class="img-caption"><strong>Figure 2.</strong> The Traceview Profile Panel</p>
95
96 <h2 id="format">Traceview File Format</h2>
97
98 <p>Tracing creates two distinct pieces of output: a <em>data</em> file, which holds the trace
99 data, and a <em>key</em> file, which provides a mapping from binary identifiers to thread and
100 method names. The files are concatenated when tracing completes, into a single <em>.trace</em>
101 file.</p>
102
103 <p class="note"><strong>Note:</strong> The previous version of Traceview did not concatenate
104 these files for you. If you have old key and data files that you'd still like to trace, you can
105 concatenate them yourself with <code>cat mytrace.key mytrace.data &gt;
106 mytrace.trace</code>.</p>
107
108 <h3 id="datafileformat">Data File Format</h3>
109
110 <p>The data file is binary, structured as follows (all values are stored in little-endian
111 order):</p>
112 <pre>
113* File format:
114* header
115* record 0
116* record 1
117* ...
118*
119* Header format:
120* u4 magic 0x574f4c53 ('SLOW')
121* u2 version
122* u2 offset to data
123* u8 start date/time in usec
124*
125* Record format:
126* u1 thread ID
127* u4 method ID | method action
128* u4 time delta since start, in usec
129</pre>
130
131 <p>The application is expected to parse all of the header fields, then seek to "offset to data"
132 from the start of the file. From there it just reads 9-byte records until EOF is reached.</p>
133
134 <p><em>u8 start date/time in usec</em> is the output from <code>gettimeofday()</code>. It's mainly there so
135 that you can tell if the output was generated yesterday or three months ago.</p>
136
137 <p><em>method action</em> sits in the two least-significant bits of the <em>method</em> word. The
138 currently defined meanings are:</p>
139
140 <ul>
141 <li>0 - method entry</li>
142
143 <li>1 - method exit</li>
144
145 <li>2 - method "exited" when unrolled by exception handling</li>
146
147 <li>3 - (reserved)</li>
148 </ul>
149
150 <p>An unsigned 32-bit integer can hold about 70 minutes of time in microseconds.</p>
151
152 <h3 id="keyfileformat">Key File Format</h3>
153
154 <p>The key file is a plain text file divided into three sections. Each section starts with a
155 keyword that begins with '*'. If you see a '*' at the start of a line, you have found the start
156 of a new section.</p>
157
158 <p>An example file might look like this:</p>
159 <pre>
160*version
1611
162clock=global
163*threads
1641 main
1656 JDWP Handler
1665 Async GC
1674 Reference Handler
1683 Finalizer
1692 Signal Handler
170*methods
1710x080f23f8 java/io/PrintStream write ([BII)V
1720x080f25d4 java/io/PrintStream print (Ljava/lang/String;)V
1730x080f27f4 java/io/PrintStream println (Ljava/lang/String;)V
1740x080da620 java/lang/RuntimeException &lt;init&gt; ()V
175[...]
1760x080f630c android/os/Debug startMethodTracing ()V
1770x080f6350 android/os/Debug startMethodTracing (Ljava/lang/String;Ljava/lang/String;I)V
178*end
179</pre>
180<p>The following list describes the major sections of a key file:</p>
181 <dl>
182 <dt><em>version section</em></dt>
183
184 <dd>The first line is the file version number, currently 1. The second line,
185 <code>clock=global</code>, indicates that we use a common clock across all threads. A future
186 version may use per-thread CPU time counters that are independent for every thread.</dd>
187
188 <dt><em>threads section</em></dt>
189
190 <dd>One line per thread. Each line consists of two parts: the thread ID, followed by a tab,
191 followed by the thread name. There are few restrictions on what a valid thread name is, so
192 include everything to the end of the line.</dd>
193
194 <dt><em>methods section</em></dt>
195
196 <dd>One line per method entry or exit. A line consists of four pieces, separated by tab marks:
197 <em>method-ID</em> [TAB] <em>class-name</em> [TAB] <em>method-name</em> [TAB]
198 <em>signature</em> . Only the methods that were actually entered or exited are included in the
199 list. Note that all three identifiers are required to uniquely identify a method.</dd>
200 </dl>
201
202 <p>Neither the threads nor methods sections are sorted.</p>
203
204 <h2 id="creatingtracefiles">Creating Trace Files</h2>
205
206 <p>To use Traceview, you need to generate log files containing the trace information you want to
207 analyze.<p>
208
209 <p>There are two ways to generate trace logs:<p>
210 <ul>
211 <li>Include the {@link android.os.Debug} class in your code and call its
212 methods to start and stop logging of trace information to disk. This method is very precise because
213 you can specify in your code exactly where to start and stop logging trace data.</li>
214 <li>Use the method profiling feature of DDMS to generate trace logs. This method is less
215 precise since you do not modify code, but rather specify when to start and stop logging with
216 a DDMS. Although you have less control on exactly where the data is logged, this method is useful
217 if you don't have access to the application's code, or if you do not need the precision of the first method.
218 </li>
219 </ul>
220
221 <p>Before you start generating trace logs, be aware of the following restrictions:</p>
222 <ul>
223 <li>If you are using the {@link android.os.Debug} class, your device or emulator must have an SD card
224 and your application must have permission to write to the SD card. </li>
225 <li>If you are using DDMS, Android 1.5 devices are not supported.</li>
226 <li>If you are using DDMS, Android 2.1 and earlier devices must
227 have an SD card present and your application must have permission to write to the SD card.
228 <li>If you are using DDMS, Android 2.2 and later devices do not need an SD card. The trace log files are
229 streamed directly to your development machine.</li>
230 </ul>
231
232 <p>This document focuses on using the {@link android.os.Debug} class to generate trace data. For more information on using DDMS
233 to generate trace data, see <a href="ddms.html#profiling">Using the Dalvik Debug Monitor Server.</a>
234 </p>
235
236 <p>To create the trace files, include the {@link android.os.Debug} class and call one of the
237 {@link android.os.Debug#startMethodTracing() startMethodTracing()} methods. In the call, you
238 specify a base name for the trace files that the system generates. To stop tracing, call {@link
239 android.os.Debug#stopMethodTracing() stopMethodTracing()}. These methods start and stop method
240 tracing across the entire virtual machine. For example, you could call
241 {@link android.os.Debug#startMethodTracing() startMethodTracing()} in
242 your activity's {@link android.app.Activity#onCreate onCreate()} method, and call
243 {@link android.os.Debug#stopMethodTracing() stopMethodTracing()} in that activity's
244 {@link android.app.Activity#onDestroy()} method.</p>
245 <pre>
246 // start tracing to "/sdcard/calc.trace"
247 Debug.startMethodTracing("calc");
248 // ...
249 // stop tracing
250 Debug.stopMethodTracing();
251</pre>
252
253 <p>When your application calls startMethodTracing(), the system creates a file called
254 <code>&lt;trace-base-name&gt;.trace</code>. This contains the binary method trace data and a
255 mapping table with thread and method names.</p>
256
257 <p>The system then begins buffering the generated trace data, until your application calls
258 stopMethodTracing(), at which time it writes the buffered data to the output file. If the system
259 reaches the maximum buffer size before stopMethodTracing() is called, the system stops tracing
260 and sends a notification to the console.</p>
261
262 <p>Interpreted code will run more slowly when profiling is enabled. Don't try to generate
263 absolute timings from the profiler results (i.e. "function X takes 2.5 seconds to run"). The
264 times are only useful in relation to other profile output, so you can see if changes have made
265 the code faster or slower.</p>
266
267 <p>When using the Android emulator, you must specify an SD card when you create your AVD because the trace files
268 are written to the SD card. Your application must have permission to write to the SD card as well.
269
270 <p>The format of the trace files is previously described <a href="#format">in this
271 document</a>.</p>
272
273 <h2 id="copyingfiles">Copying Trace Files to a Host Machine</h2>
274
275 <p>After your application has run and the system has created your trace files
276 <code>&lt;trace-base-name&gt;.trace</code> on a device or emulator, you must copy those files to
277 your development computer. You can use <code>adb pull</code> to copy the files. Here's an example
278 that shows how to copy an example file, calc.trace, from the default location on the emulator to
279 the /tmp directory on the emulator host machine:</p>
280 <pre>
281adb pull /sdcard/calc.trace /tmp
282</pre>
283
284 <h2 id="runningtraceview">Viewing Trace Files in Traceview</h2>
285
286 <p>To run Traceview and view the trace files, enter <code>traceview
287 &lt;trace-base-name&gt;</code>. For example, to run Traceview on the example files copied in the
288 previous section, use:</p>
289 <pre>
290traceview /tmp/calc
291</pre>
292
293 <p class="note"><strong>Note:</strong> If you are trying to view the trace logs of an application
294 that is built with ProGuard enabled (release mode build), some method and member names might be obfuscated.
295 You can use the Proguard <code>mapping.txt</code> file to figure out the original unobfuscated names. For more information
296 on this file, see the <a href="{@docRoot}/guide/developing/tools/proguard.html>Proguard</a> documentation.</p>
297
298 <h2 id="dmtracedump">Using dmtracdedump</h2>
299
300 <p><code>dmtracedump</code> is a tool that gives you an alternate way of generating
301 graphical call-stack diagrams from trace log files. The tool uses the Graphviz Dot utility to
302 create the graphical output, so you need to install Graphviz before running dmtracedump.</p>
303
304 <p>The dmtracedump tool generates the call stack data as a tree diagram, with each call
305 represented as a node. It shows call flow (from parent node to child nodes) using arrows. The
306 diagram below shows an example of dmtracedump output.</p>
307 <img src=
308 "{@docRoot}images/tracedump.png"
309 width="485"
310 height="401" />
311 <p class="image-caption><strong>Figure 3.</strong> Screenshot of dmtracedump</p>
312
313 <p>For each node, dmtracedump shows <code>&lt;ref&gt;
314 <em>callname</em> (&lt;inc-ms&gt;, &lt;exc-ms&gt;,&lt;numcalls&gt;)</code>, where</p>
315
316 <ul>
317 <li><code>&lt;ref&gt;</code> -- Call reference number, as used in trace logs</li>
318
319 <li><code>&lt;inc-ms&gt;</code> -- Inclusive elapsed time (milliseconds spent in method,
320 including all child methods)</li>
321
322 <li><code>&lt;exc-ms&gt;</code> -- Exclusive elapsed time (milliseconds spent in method,
323 not including any child methods)</li>
324
325 <li><code>&lt;numcalls&gt;</code> -- Number of calls</li>
326 </ul>
327
328 <p>The usage for dmtracedump is:</p>
329 <pre>
330dmtracedump [-ho] [-s sortable] [-d trace-base-name] [-g outfile] &lt;trace-base-name&gt;
331</pre>
332
333 <p>The tool then loads trace log data from <code>&lt;trace-base-name&gt;.data</code> and
334 <code>&lt;trace-base-name&gt;.key</code>. The table below lists the options for dmtracedump.</p>
335
336 <table>
337 <tr>
338 <th>Option</th>
339
340 <th>Description</th>
341 </tr>
342
343 <tr>
344 <td><code>-d&nbsp;&lt;trace-base-name&gt;</code></td>
345
346 <td>Diff with this trace name</td>
347 </tr>
348
349 <tr>
350 <td><code>-g&nbsp;&lt;outfile&gt;</code></td>
351
352 <td>Generate output to &lt;outfile&gt;</td>
353 </tr>
354
355 <tr>
356 <td><code>-h</code></td>
357
358 <td>Turn on HTML output</td>
359 </tr>
360
361 <tr>
362 <td><code>-o</code></td>
363
364 <td>Dump the trace file instead of profiling</td>
365 </tr>
366
367 <tr>
368 <td><code>-d&nbsp;&lt;trace-base-name&gt;</code></td>
369
370 <td>URL base to the location of the sortable javascript file</td>
371 </tr>
372
373 <tr>
374 <td><code>-t&nbsp;&lt;percent&gt;</code></td>
375
376 <td>Minimum threshold for including child nodes in the graph (child's inclusive time as a
377 percentage of parent inclusive time). If this option is not used, the default threshold
378 is 20%.</td>
379 </tr>
380 </table>
381 </dd>
382 </dl>
383
384
385
386 <h2 id="knownissues">Traceview Known Issues</h2>
387
388 <dl>
389 <dt>Threads</dt>
390
391 <dd>
392 Traceview logging does not handle threads well, resulting in these two problems:
393
394 <ol>
395 <li>If a thread exits during profiling, the thread name is not emitted;</li>
396
397 <li>The VM reuses thread IDs. If a thread stops and another starts, they may get the same
398 ID.</li>
399 </ol>
400 </dd>
401
402 </dl>