Also update some of the out-of-date aspects of the systrace help page. Change-Id: I869f6d481ecc2835ea8713bb46f6e5d550abea98
288 lines
13 KiB
Plaintext
288 lines
13 KiB
Plaintext
page.title=Analyzing UI Performance with Systrace
|
|
page.tags=systrace,speed
|
|
parent.title=Debugging
|
|
parent.link=index.html
|
|
@jd:body
|
|
|
|
<div id="qv-wrapper">
|
|
<div id="qv">
|
|
<h2>In this document</h2>
|
|
<ol>
|
|
<li><a href="#overview">Overview</a></li>
|
|
<li><a href="#generate">Generating a Trace</a></li>
|
|
<li><a href="#analysis">Analyzing a Trace</a>
|
|
<ol>
|
|
<li><a href="#frames">Inspecting Frames</a></li>
|
|
<li><a href="#alerts">Investigating Alerts</a></li>
|
|
</ol>
|
|
</li>
|
|
<li><a href="#app-trace">Tracing Application Code</a></li>
|
|
</ol>
|
|
<h2>See also</h2>
|
|
<ol>
|
|
<li><a href="{@docRoot}tools/help/systrace.html">Systrace</a></li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
|
|
<p>While developing your application, you should check that user interactions are buttery smooth,
|
|
running at a consistent 60 frames per second. If something goes wrong, and a frame gets dropped, the
|
|
first step in fixing the problem is understanding what the system is doing.</p>
|
|
|
|
<p>The Systrace tool allows you to collect and inspect timing information across an entire Android
|
|
device, which is called a <em>trace</em>. It shows where time and CPU cycles are being spent,
|
|
displaying what each thread and process is doing at any given time. It also inpects the captured
|
|
tracing information to highlight problems that it observes, from list item recycling to rendering
|
|
content, and provide recommendations about how to fix them. This document explains how to navigate
|
|
the trace files produced by the tool, and use them to analyze the performance of an application's
|
|
user interface (UI).</p>
|
|
|
|
<h2 id="overview">Overview</h2>
|
|
|
|
<p>Systrace helps you analyze how the execution of your application fits into the many running
|
|
systems on an Android device. It puts together system and application thread execution on a common
|
|
timeline. In order to analyze your app with Systrace, you first collect a trace log of your app, and
|
|
the system activity. The generated trace allows you to view highly detailed, interactive reports
|
|
showing everything happening the system for the traced duration.</p>
|
|
|
|
<img src="{@docRoot}images/systrace/overview.png" alt="Systrace example overview" id="figure1" />
|
|
<p class="img-caption">
|
|
<strong>Figure 1.</strong> An example Systrace, showing 5 seconds of scrolling an app when it
|
|
is not performing well.
|
|
</p>
|
|
|
|
<p>Figure 1. shows a trace captured while scrolling an app that is not rendering smoothly. By
|
|
default, a zoomed out view of the traced duration is shown. The horizontal axis is time, and trace
|
|
events are grouped by process, and then by thread on the vertical axis.</p>
|
|
|
|
<p>The groupings are in the order Kernel, SurfaceFlinger (the android compositor process), followed
|
|
by apps, each labeled by package name. Each app process contains all of the tracing signals from
|
|
each thread it contains, including a hierarchy of high level tracing events based on the enabled
|
|
tracing categories.</p>
|
|
|
|
|
|
<h2 id="generate">Generating a Trace</h2>
|
|
|
|
<p>In order to create a trace of your application, you must perform a few setup steps. First, you
|
|
must have a device running Android 4.1 (API 16) or higher. Set up the device
|
|
for <a href="{@docRoot}tools/device.html#setting-up">debugging</a>, connect it to your development
|
|
system, and install your application. Some types of trace information, specifically disk activity
|
|
and kernel work queues, require that you have root access to the device. However, most Systrace log
|
|
data only requires that the device be enabled for developer debugging.</p>
|
|
|
|
<p>Systrace traces can be run either from
|
|
a <a href="{@docRoot}tools/help/systrace.html#options">command line</a> or from a
|
|
<a href="{@docRoot}tools/help/systrace.html#gui">graphical user interface</a>. This guide focuses on
|
|
using the command line options.</p>
|
|
|
|
<h3 id="running-4.3">Tracing on Android 4.3 and higher</h3>
|
|
|
|
<p>To run a trace on Android 4.3 and higher devices:</p>
|
|
|
|
<ol>
|
|
<li>Make sure the device is connected through a USB cable and is
|
|
<a href="{@docRoot}tools/device.html#setting-up">enabled for debugging</a>.</li>
|
|
<li>Run the trace with the options you want, for example:
|
|
<pre>
|
|
$ cd android-sdk/platform-tools/systrace
|
|
$ python systrace.py --time=10 -o mynewtrace.html sched gfx view wm
|
|
</pre>
|
|
</li>
|
|
<li>On the device, execute any user actions you want be included in the trace.</li>
|
|
</ol>
|
|
|
|
<p>For more information on the available options for running Systrace, see the
|
|
<a href="#options-4.3">Systrace</a> help page.</p>
|
|
|
|
|
|
<h3 id="running-4.2">Tracing on Android 4.2 and lower</h3>
|
|
|
|
<p>To use Systrace effectively with devices running Android 4.2 and lower,
|
|
you must configure the types of processes you want to trace before running a trace.
|
|
The tool can gather the following types of process information:</p>
|
|
|
|
<ul>
|
|
<li>General system processes such as graphics, audio and input processes (selected using trace
|
|
<a href="#tags">category tags</a>).</li>
|
|
<li>Low level system information such as CPU, kernel and disk activity (selected using
|
|
<a href="#options">options</a>).</li>
|
|
</ul>
|
|
|
|
<p>To set trace tags for Systrace using the command-line:</p>
|
|
|
|
<ol>
|
|
<li>Use the {@code --set-tags} option:
|
|
<pre>
|
|
$ cd android-sdk/platform-tools/systrace
|
|
$ python systrace.py --set-tags=gfx,view,wm
|
|
</pre>
|
|
</li>
|
|
<li>Stop and restart the {@code adb} shell to enable tracing of these processes.
|
|
<pre>
|
|
$ adb shell stop
|
|
$ adb shell start
|
|
</pre></li>
|
|
</ol>
|
|
|
|
<p>To set trace tags for Systrace using the device user interface:</p>
|
|
|
|
<ol>
|
|
<li>On the device connected for tracing, navigate to: <strong>Settings >
|
|
Developer options > Monitoring > Enable traces</strong>.</li>
|
|
<li>Select the categories of processes to be traced and click <strong>OK</strong>.</li>
|
|
</ol>
|
|
|
|
<p class="note">
|
|
<strong>Note:</strong> The {@code adb} shell does not have to be stopped and restarted when
|
|
selecting trace tags using this method.
|
|
</p>
|
|
|
|
<p>After you have configured the category tags for your trace, you can start collecting
|
|
information for analysis.</p>
|
|
|
|
<p>To run a trace using the current trace tag settings:</p>
|
|
|
|
<ol>
|
|
<li>Make sure the device is connected through a USB cable and is
|
|
<a href="{@docRoot}tools/device.html#setting-up">enabled for debugging</a>.</li>
|
|
<li>Run the trace with the low-level system trace options and limits you want, for example:
|
|
<pre>
|
|
$ python systrace.py --cpu-freq --cpu-load --time=10 -o mytracefile.html
|
|
</pre>
|
|
</li>
|
|
<li>On the device, execute any user actions you want be included in the trace.</li>
|
|
</ol>
|
|
|
|
<p>For more information on the available options for running Systrace, see the
|
|
<a href="#options-pre-4.3">Systrace</a> help page.</p>
|
|
|
|
|
|
<h2 id="analysis">Analyzing a Trace</h2>
|
|
|
|
<p>After you have generated a trace, open the output html file using a web browser. This section
|
|
explains how to analyze and interpret the information that the tool produces to find and fix UI
|
|
performance problems.</p>
|
|
|
|
<h3 id="frames">Inspecting Frames</h3>
|
|
|
|
<p>Each app that is rendering frames shows a row of frame circles, which are typically colored
|
|
green. Circles that are colored yellow or red, exceeding the 16.6 millisecond run time limit
|
|
required to maintain a stable 60 frames per second. Zoom in using the 'w' key to see the frames of
|
|
your application, and look for long-running frames getting in the way of smoothness.</p>
|
|
|
|
<p class="note">
|
|
<strong>Note:</strong> Hit the '?' key, or the button in the top right for help navigating the
|
|
trace.
|
|
</p>
|
|
|
|
<img src="{@docRoot}images/systrace/frame-unselected.png" alt="Zoomed in view of a frame" id="figure2" />
|
|
<p class="img-caption">
|
|
<strong>Figure 2.</strong> Systrace display after zooming in on a long-running frame.
|
|
</p>
|
|
|
|
<p>Clicking on one such frame highlights it, focusing only on the work done by the system for that
|
|
frame. On devices running Android 5.0 (API level 21) or higher, this work is split between the UI
|
|
Thread and RenderThread. On prior versions, all work in creating a frame is done on the UI
|
|
Thread.</p>
|
|
|
|
<p>Click on individual components of the frame to see how long they took to run. Some events, such
|
|
as <em>performTraversals</em>, describe what the system is doing in that method when you select
|
|
it. Selecting a frame displays any alerts present in that frame.</p>
|
|
|
|
<h3 id="alerts">Investigating Alerts</h3>
|
|
|
|
<p>Systrace does automatic analysis of the events in the trace, and highlights many performance
|
|
problems as alerts, suggesting what to do next.</p>
|
|
|
|
<img src="{@docRoot}images/systrace/frame-selected.png" alt="Problematic frame selected" id="figure3" />
|
|
<p class="img-caption">
|
|
<strong>Figure 3.</strong> Selecting the problematic frame, an alert is shown identifying a problem.
|
|
</p>
|
|
|
|
<p>After you select a slow frame such as the one shown in Figure 3, an alert may be displayed. In
|
|
the case above, it calls out that the primary problem with the frame is too much work being done
|
|
inside {@link android.widget.ListView} recycling and rebinding. There are links to the relevant
|
|
events in the trace, which can be followed to explain more about what the system is doing during
|
|
this time.</p>
|
|
|
|
<p>If you see too much work being done on the UI thread, as in this case with this
|
|
{@link android.widget.ListView} work, you can
|
|
use <a href="{@docRoot}tools/debugging/debugging-tracing.html">Traceview</a>, the app code profiling
|
|
tool, to investigate exactly what is taking so much time.</p>
|
|
|
|
<p>Note that you can also find about every alert in the trace by clicking the <em>Alerts</em> tab to
|
|
the far right of the window. Doing so expands the Alerts panel, where you can see every alert that
|
|
the tool discovered in your trace, along with an occurrence count.</p>
|
|
|
|
<img src="{@docRoot}images/systrace/frame-selected-alert-tab.png" alt="Alert tab shown" id="figure4" />
|
|
<p class="img-caption">
|
|
<strong>Figure 4.</strong> Clicking the Alert button to the right reveals the alert tab.
|
|
</p>
|
|
|
|
<p>The Alerts panel helps you see which problems occur in the trace, and how often they contribute
|
|
to jank. Think of the alerts panel as a list of bugs to be fixed, often a tiny change or improvement
|
|
in one area can eliminate an entire class of alerts from your application!</p>
|
|
|
|
|
|
<h2 id="app-trace">Tracing Application Code</h2>
|
|
|
|
<p>The tracing signals defined by the framework do not have visibility into everything your
|
|
application is doing, so you may want to add your own. In Android 4.3 (API level 18) and higher, you
|
|
can use the methods of the {@link android.os.Trace} class to add signals to your code. This
|
|
technique can help you see what work your application's threads are doing at any given time. Tracing
|
|
begin and end events do add overhead while a trace is being captured, a few microseconds each, but
|
|
sprinkling in a few per frame, or per worker thread task can go a long way to adding context to a
|
|
trace of your app.</p>
|
|
|
|
<p>The following code example shows how to use the {@link android.os.Trace} class to track
|
|
execution of an application method, including two nested code blocks within that method.</p>
|
|
|
|
<pre>
|
|
public void ProcessPeople() {
|
|
Trace.beginSection("ProcessPeople");
|
|
try {
|
|
Trace.beginSection("Processing Jane");
|
|
try {
|
|
// code for Jane task...
|
|
} finally {
|
|
Trace.endSection(); // ends "Processing Jane"
|
|
}
|
|
|
|
Trace.beginSection("Processing John");
|
|
try {
|
|
// code for John task...
|
|
} finally {
|
|
Trace.endSection(); // ends "Processing John"
|
|
}
|
|
} finally {
|
|
Trace.endSection(); // ends "ProcessPeople"
|
|
}
|
|
}
|
|
</pre>
|
|
|
|
<!-- todo: move these two Notes to the android.os.Trace class -->
|
|
<p class="note">
|
|
<strong>Note:</strong> When you nest trace calls within each other, the
|
|
{@link android.os.Trace#endSection} method ends the most recently called
|
|
{@link android.os.Trace#beginSection} method. This means that a trace started within another
|
|
trace cannot extend beyond the end of the enclosing trace, so make sure your beginning and
|
|
ending method calls are properly matched to measure your applications processing.
|
|
</p>
|
|
|
|
<p class="note">
|
|
<strong>Note:</strong> Traces must begin and end on the same thread. Do not call
|
|
{@link android.os.Trace#beginSection} on one thread of execution and then attempt to end the
|
|
trace with a call to {@link android.os.Trace#endSection} on another thread.
|
|
</p>
|
|
|
|
<p>When using application-level tracing with Systrace, you must specify the package name of your
|
|
application in the user interface or specify the {@code -a} or {@code --app=} options on the
|
|
command line. For more information, see the
|
|
<a href="{@docRoot}tools/help/systrace.html">Systrace usage guide</a>.</p>
|
|
|
|
<p>You should enable app level tracing when profiling your app, even if you have not added signals
|
|
yourself. Library code can include very useful tracing signals when you enable application-level
|
|
tracing. The {@link android.support.v7.widget.RecyclerView} class is a great example of this,
|
|
providing information about several important stages of work it executes.</p>
|
|
|