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