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