|  | 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> | 
|  |  |