Home | History | Annotate | Download | only in performance
      1 page.title=Threading Performance
      2 @jd:body
      3 
      4 <div id="qv-wrapper">
      5 <div id="qv">
      6 
      7 <h2>In this document</h2>
      8 <ol>
      9 <li><a href="#main">Main Thread</a>
     10   <ol>
     11     <li><a href="#internals">Internals</a></li>
     12   </ol>
     13 </li>
     14 <li><a href="#references">Threading and UI Object References</a>
     15   <ol>
     16     <li><a href="#explicit">Explicit references</a></li>
     17     <li><a href="#implicit">Implicit references</a></li>
     18   </ol>
     19 </li>
     20 <li><a href="#lifecycles">Threading and App and Activity Lifecycles</a>
     21    <ol>
     22       <li><a href="#persisting">Persisting threads</a></li>
     23       <li><a href="#priority">Thread priority</a></li>
     24    </ol>
     25       </li>
     26 <li><a href="#helper">Helper Classes for Threading</a>
     27    <ol>
     28       <li><a href="#asynctask">The AsyncTask class</a></li>
     29       <li><a href="#handlerthread">The HandlerThread class</a></li>
     30       <li><a href="#threadpool">The ThreadPoolExecutor class</a></li>
     31    </ol>
     32       </li>
     33 </ol>
     34 </div>
     35 </div>
     36 
     37 <p>
     38 Making adept use of threads on Android can help you boost your apps
     39 performance. This page discusses several aspects of working with threads:
     40 working with the UI, or main, thread; the relationship between app lifecycle and
     41 thread priority; and, methods that the platform provides to help manage thread
     42 complexity. In each of these areas, this page describes potential pitfalls and
     43 strategies for avoiding them.
     44 </p>
     45 <h2 id="main">Main Thread</h2>
     46 <p>
     47 When the user launches your app, Android creates a new <a
     48 href="{@docRoot}guide/components/fundamentals.html">Linux
     49 process</a> along with an execution thread. This <strong>main thread,</strong>
     50 also known as the UI thread, is responsible for everything that happens
     51 onscreen. Understanding how it works can help you design your app to use the
     52 main thread for the best possible performance.
     53 </p>
     54 <h3 id="internals">Internals</h3>
     55 <p>
     56 The main thread has a very simple design: Its only job is to take and execute
     57 blocks of work from a thread-safe work queue until its app is terminated. The
     58 framework generates some of these blocks of work from a variety of places. These
     59 places include callbacks associated with lifecycle information, user events such
     60 as input, or events coming from other apps and processes. In addition, app can
     61 explicitly enqueue blocks on their own, without using the framework.
     62 </p>
     63 <p>
     64 Nearly <a
     65 href="https://www.youtube.com/watch?v=qk5F6Bxqhr4&index=1&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">any
     66 block of code your app executes</a> is tied to an event callback, such as input,
     67 layout inflation, or draw. When something triggers an event, the thread where the event
     68 happened pushes the event out of itself, and into the main threads message
     69 queue. The main thread can then service the event.
     70 </p>
     71 
     72 <p>
     73 While an animation or screen update is occurring, the system tries to execute a
     74 block of work (which is responsible for drawing the screen) every 16ms or so, in
     75 order to render smoothly at <a
     76 href="https://www.youtube.com/watch?v=CaMTIgxCSqU&index=62&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">60
     77 frames per second</a>. For the system to reach this goal, some operations must
     78 happen on the main thread. However, when the main threads messaging queue
     79 contains tasks that are either too numerous or too long for the main thread to
     80 complete work within the 16ms window, the app should move this work to a worker
     81 thread. If the main thread cannot finish executing blocks of work within 16ms,
     82 the user may observe hitching, lagging, or a lack of UI responsiveness to input.
     83 If the main thread blocks for approximately five seconds, the system displays
     84 the <a
     85 href="{@docRoot}training/articles/perf-anr.html"><em>Application
     86 Not Responding</em></a> (ANR) dialog, allowing the user to close the app directly.
     87 </p>
     88 <p>
     89 Moving numerous or long tasks from the main thread, so that they dont interfere
     90 with smooth rendering and fast responsiveness to user input, is the biggest
     91 reason for you to adopt threading in your app.
     92 </p>
     93 <h2 id="references">Threading and UI Object References</h2>
     94 <p>
     95 By design, <a
     96 href="https://www.youtube.com/watch?v=tBHPmQQNiS8&index=3&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">Android
     97 UI objects are not thread-safe</a>. An app is expected to create, use, and
     98 destroy UI objects, all on the main thread. If you try to modify
     99 or even reference a UI object in a thread other than the main thread, the result
    100 can be exceptions, silent failures, crashes, and other undefined misbehavior.
    101 </p>
    102 <p>
    103 Issues with references fall into two distinct categories: explicit references
    104 and implicit references.
    105 </p>
    106 <h3 id="explicit">Explicit references</h3>
    107 <p>
    108 Many tasks on non-main threads have the end goal of updating UI objects.
    109 However, if one of these threads accesses an object in the view hierarchy,
    110 application instability can result: If a worker thread changes the properties of
    111 that object at the same time that any other thread is referencing the object,
    112 the results are undefined.
    113 </p>
    114 <p>
    115 For example, consider an app that holds a direct reference to a UI object on a
    116 worker thread. The object on the worker thread may contain a reference to a
    117 {@link android.view.View}; but before the work completes, the {@link android.view.View} is
    118 removed from the view hierarchy. When these two actions happen simultaneously,
    119 the reference keeps the {@link android.view.View} object in memory and sets properties on it.
    120 However, the user never sees
    121 this object, and the app deletes the object once the reference to it is gone.
    122 </p>
    123 
    124 <p>
    125 In another example, {@link android.view.View} objects contain references to the activity
    126 that owns them. If
    127 that activity is destroyed, but there remains a threaded block of work that
    128 references it&mdash;directly or indirectly&mdash;the garbage collector will not collect
    129 the activity until that block of work finishes executing.
    130 </p>
    131 <p>
    132 This scenario can cause a problem in situations where threaded work may be in
    133 flight while some activity lifecycle event, such as a screen rotation, occurs.
    134 The system wouldnt be able to perform garbage collection until the in-flight
    135 work completes. As a result, there may be two {@link android.app.Activity} objects in
    136 memory until garbage collection can take place.
    137 </p>
    138 
    139 <p>
    140 With scenarios like these, we suggest that your app not include explicit
    141 references to UI objects in threaded work tasks. Avoiding such references helps you avoid
    142 these types of memory leaks, while also steering clear of threading contention.
    143 </p>
    144 <p>
    145 In all cases, your app should only update UI objects on the main thread. This
    146 means that you should craft a negotiation policy that allows multiple threads to
    147 communicate work back to the main thread, which tasks the topmost activity or
    148 fragment with the work of updating the actual UI object.
    149 </p>
    150 <h3 id="implicit">Implicit references</h3>
    151 <p>
    152 A common code-design flaw with threaded objects can be seen in the snippet of
    153 code below:
    154 </p>
    155 <pre class="prettyprint">
    156 public class MainActivity extends Activity {
    157   // ...
    158   public class MyAsyncTask extends AsyncTask<Void, Void, String>   {
    159     &#64;Override protected String doInBackground(Void... params) {...}
    160     &#64;Override protected void onPostExecute(String result) {...}
    161   }
    162 }
    163 </pre>
    164 <p>
    165 The flaw in this snippet is that the code declares the threading object
    166 {@code MyAsyncTask} as an inner class of some activity. This declaration creates an
    167 implicit reference to the enclosing {@link android.app.Activity} object.
    168 As a result, the object contains a reference to the activity until the
    169 threaded work completes, causing a delay in the destruction of the referenced activity.
    170 This delay, in turn, puts more pressure on memory.
    171 </p>
    172 <p>
    173 A direct solution to this problem would be to define your overloaded class
    174 instances in their own files, thus removing the implicit reference.
    175 </p>
    176 <p>
    177 Another solution is to declare the {@link android.os.AsyncTask} object
    178 as a static nested class.  Doing so eliminates the implicit reference problem
    179 because of the way a static nested
    180 class differs from an inner class: An instance of an inner class requires an
    181 instance of the outer class to be instantiated, and has direct access to the
    182 methods and fields of its enclosing instance. By contrast, a static nested class
    183 does not require a reference to an instance of enclosing class, so it contains
    184 no references to the outer class members.
    185 </p>
    186 <pre class="prettyprint">
    187 public class MainActivity extends Activity {
    188   // ...
    189   Static public class MyAsyncTask extends AsyncTask<Void, Void, String>   {
    190     &#64;Override protected String doInBackground(Void... params) {...}
    191     &#64;Override protected void onPostExecute(String result) {...}
    192   }
    193 }
    194 </pre>
    195 <h2 id="lifecycles">Threading and App and Activity Lifecycles</h2>
    196 <p>
    197 The app lifecycle can affect how threading works in your application.
    198 You may need to decide that a thread should, or should not, persist after an
    199 activity is destroyed. You should also be aware of the relationship between
    200 thread prioritization and whether an activity is running in the foreground or
    201 background.
    202 </p>
    203 <h3 id="persisting">Persisting threads</h3>
    204 <p>
    205 Threads persist past the lifetime of the activities that spawn them. Threads
    206 continue to execute, uninterrupted, regardless of the creation or destruction of
    207 activities. In some cases, this persistence is undesirable.
    208 </p>
    209 <p>
    210 Consider a case in which an activity spawns a set of threaded work blocks, and
    211 is then destroyed before a worker thread can execute the blocks. What should the
    212 app do with the blocks that are in flight?
    213 </p>
    214 
    215 <p>
    216 If the blocks were going to update a UI that no longer exists, theres no reason
    217 for the work to continue. For example, if the work is to load user information
    218 from a database, and then update views, the thread is no longer necessary.
    219 </p>
    220 
    221 <p>
    222 By contrast, the work packets may have some benefit not entirely related to the
    223 UI. In this case, you should persist the thread. For example, the packets may be
    224 waiting to download an image, cache it to disk, and update the associated
    225 {@link android.view.View} object. Although the object no longer exists, the acts of downloading and
    226 caching the image may still be helpful, in case the user returns to the
    227 destroyed activity.
    228 </p>
    229 
    230 <p>
    231 Managing lifecycle responses manually for all threading objects can become
    232 extremely complex. If you dont manage them correctly, your app can suffer from
    233 memory contention and performance issues. <a
    234 href="{@docRoot}guide/components/loaders.html">Loaders</a>
    235 are one solution to this problem. A loader facilitates asynchronous loading of
    236 data, while also persisting information through configuration changes.
    237 </p>
    238 <h3 id="priority">Thread priority</h3>
    239 <p>
    240 As described in <a
    241 href="{@docRoot}guide/topics/processes/process-lifecycle.html">Processes
    242 and the Application Lifecycle</a>, the priority that your apps threads receive
    243 depends partly on where the app is in the app lifecycle. As you create and
    244 manage threads in your application, its important to set their priority so that
    245 the right threads get the right priorities at the right times. If set too high,
    246 your thread may interrupt the UI thread and RenderThread, causing your app to
    247 drop frames. If set too low, you can make your async tasks (such as image
    248 loading) slower than they need to be.
    249 </p>
    250 <p>
    251 Every time you create a thread, you should call
    252 {@link android.os.Process#setThreadPriority(int, int) setThreadPriority()}.
    253 The systems thread
    254 scheduler gives preference to threads with high priorities, balancing those
    255 priorities with the need to eventually get all the work done. Generally, threads
    256 in the <a
    257 href="https://www.youtube.com/watch?v=NwFXVsM15Co&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=9">foreground
    258 group get about 95%</a> of the total execution time from the device, while the
    259 background group gets roughly 5%.
    260 </p>
    261 <p>
    262 The system also assigns each thread its own priority value, using the
    263 {@link android.os.Process} class.
    264 </p>
    265 <p>
    266 By default, the system sets a threads priority to the same priority and group
    267 memberships as the spawning thread. However, your application can explicitly
    268 adjust thread priority by using
    269 {@link android.os.Process#setThreadPriority(int, int) setThreadPriority()}.
    270 </p>
    271 <p>
    272 The {@link android.os.Process}
    273 class</a> helps reduce complexity in assigning priority values by providing a
    274 set of constants that your app can use to set thread priorities. For example, <a
    275 href="{@docRoot}reference/android/os/Process.html#THREAD_PRIORITY_DEFAULT">THREAD_PRIORITY_DEFAULT</a>
    276 represents the default value for a thread. Your app should set the thread's priority to <a
    277 href="{@docRoot}reference/android/os/Process.html#THREAD_PRIORITY_BACKGROUND">THREAD_PRIORITY_BACKGROUND</a>
    278 for threads that are executing less-urgent work.
    279 </p>
    280 <p>
    281 Your app can use the <a
    282 href="{@docRoot}reference/android/os/Process.html#THREAD_PRIORITY_LESS_FAVORABLE">THREAD_PRIORITY_LESS_FAVORABLE</a>
    283 and <a
    284 href="{@docRoot}reference/android/os/Process.html#THREAD_PRIORITY_MORE_FAVORABLE">THREAD_PRIORITY_MORE_FAVORABLE</a>
    285 constants as incrementers to set relative priorities. A list of all of these
    286 enumerated states and modifiers appears in the reference documentation for
    287 the {@link android.os.Process#THREAD_PRIORITY_AUDIO} class.
    288 
    289 For more information on
    290 managing threads, see the reference documentation about the
    291 {@link java.lang.Thread} and {@link android.os.Process} classes.
    292 </p>
    293 <p>
    294 https://developer.android.com/reference/android/os/Process.html#THREAD_PRIORITY_AUDIO
    295 </p>
    296 <h2 id="helper">Helper Classes for Threading</h2>
    297 <p>
    298 The framework provides the same Java classes & primitives to facilitate
    299 threading, such as the {@link java.lang.Thread} and
    300 {@link java.lang.Runnable} classes.
    301 In order to help reduce the cognitive load associated with
    302 of developing threaded applications for
    303 Android, the framework provides a set of helpers which can aide in development.
    304 Each helper class has a specific set of performance nuances that make them
    305 unique for a specific subset of threading problems. Using the wrong class for
    306 the wrong situation can lead to performance issues.
    307 </p>
    308 <h3 id="asynctask">The AsyncTask class</h3>
    309 <p>
    310 
    311 The {@link android.os.AsyncTask} class
    312 is a simple, useful primitive for apps that need to quickly move work from the
    313 main thread onto worker threads. For example, an input event might trigger the
    314 need to update the UI with a loaded bitmap. An {@link android.os.AsyncTask}
    315 object can offload the
    316 bitmap loading and decoding to an alternate thread; once that processing is
    317 complete, the {@link android.os.AsyncTask} object can manage receiving the work
    318 back on the main thread to update the UI.
    319 </p>
    320 <p>
    321 When using {@link android.os.AsyncTask}, there are a few important performance
    322 aspects to keep in
    323 mind. First, by default, an app pushes all of the {@link android.os.AsyncTask}
    324 objects it creates into a
    325 single thread. Therefore, they execute in serial fashion, and&mdash;as with the
    326 main
    327 thread&mdash;an especially long work packet can block the queue. For this reason,
    328 we suggest that you only use {@link android.os.AsyncTask} to handle work items
    329 shorter than 5ms in duration.
    330 </p>
    331 <p>
    332 {@link android.os.AsyncTask} objects are also the most common offenders
    333 for implicit-reference issues.
    334 {@link android.os.AsyncTask} objects present risks related to explicit
    335 references, as well, but these are
    336 sometimes easier to work around. For example, an {@link android.os.AsyncTask}
    337 may require a reference to a UI object in order to update the UI object
    338 properly once {@link android.os.AsyncTask} executes its callbacks on the
    339 main thread. In such a situation, you
    340 can use a {@link java.lang.ref.WeakReference}
    341 to store a reference to the required UI object, and access the object once the
    342 {@link android.os.AsyncTask} is operating on the main thread. To be clear,
    343 holding a {@link java.lang.ref.WeakReference}
    344 to an object does not make the object thread-safe; the
    345 {@link java.lang.ref.WeakReference} merely
    346 provides a method to handle issues with explicit references and garbage
    347 collection.
    348 </p>
    349 <h3 id="handlerthread">The HandlerThread class</h3>
    350 <p>
    351 While an {@link android.os.AsyncTask}
    352 is useful,<a
    353 href="https://www.youtube.com/watch?v=adPLIAnx9og&index=5&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">
    354 it may not always be the right solution</a> to your threading problem. Instead,
    355 you may need a more traditional approach to executing a block of work on a
    356 longer running thread, and some ability to manage that workflow manually.
    357 </p>
    358 
    359 <p>
    360 Consider a common challenge with getting preview frames from your
    361 {@link android.hardware.Camera} object.
    362  When you register for Camera preview frames, you receive them in the
    363  {@link android.hardware.Camera.PreviewCallback#onPreviewFrame(byte[], android.hardware.Camera) onPreviewFrame()}
    364 callback, which is invoked on the event thread it was called from. If this
    365 callback were invoked on the UI thread, the task of dealing with the huge pixel
    366 arrays would be interfering with rendering and event processing work. The same
    367 problem applies to {@link android.os.AsyncTask}, which also executes jobs serially and is
    368 susceptible to blocking.
    369 </p>
    370 <p>
    371 This is a situation where a handler thread would be appropriate: A handler thread
    372 is effectively a long-running thread that grabs work from a queue, and operates
    373 on it. In this example, when your app delegates the
    374 {@link android.hardware.Camera#open Camera.open()} command to a
    375 block of work on the handler thread, the associated
    376  {@link android.hardware.Camera.PreviewCallback#onPreviewFrame(byte[], android.hardware.Camera) onPreviewFrame()}
    377 callback
    378 lands on the handler thread, rather than the UI or {@link android.os.AsyncTask}
    379 threads. So, if youre going to be doing long-running work on the pixels, this
    380 may be a better solution for you.
    381 </p>
    382 <p>
    383 When your app creates a thread using {@link android.os.HandlerThread}, dont
    384 forget to set the threads
    385 <a href="https://www.youtube.com/watch?v=NwFXVsM15Co&index=9&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">
    386 priority based on the type of work its doing</a>. Remember, CPUs can only
    387 handle a small number of threads in parallel. Setting the priority helps
    388 the system know the right ways to schedule this work when all other threads
    389 are fighting for attention.
    390 </p>
    391 <h3 id="threadpool">The ThreadPoolExecutor class</h3>
    392 <p>
    393 There are certain types of work that can be reduced to highly parallel,
    394 distributed tasks. One such task, for example, is calculating a filter for each
    395 8x8 block of an 8 megapixel image. With the sheer volume of work packets this
    396 creates, <a
    397 href="https://www.youtube.com/watch?v=uCmHoEY1iTM&index=6&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE">
    398 {@code AsyncTask} and {@code HandlerThread} arent appropriate
    399 classes</a>. The single-threaded nature of {@link android.os.AsyncTask} would
    400 turn all the threadpooled work into a linear system.
    401 Using the {@link android.os.HandlerThread} class, on the other hand, would
    402 require the programmer to manually manage load balancing between a group of
    403 threads.
    404 </p>
    405 
    406 <p>
    407 {@link java.util.concurrent.ThreadPoolExecutor} is a helper class to make
    408 this process easier. This class manages the creation of a group of threads, sets
    409 their priorities, and manages how work is distributed among those threads.
    410 As workload increases or decreases, the class spins up or destroys more threads
    411 to adjust to the workload.
    412 </p>
    413 <p>
    414 This class also helps your app spawn an optimum number of threads. When it
    415 constructs a {@link java.util.concurrent.ThreadPoolExecutor}
    416 object, the app sets a minimum and maximum
    417 number of threads. As the workload given to the
    418 {@link java.util.concurrent.ThreadPoolExecutor} increases,
    419 the class will take the initialized minimum and maximum thread counts into
    420 account, and consider the amount of pending work there is to do. Based on these
    421 factors, {@link java.util.concurrent.ThreadPoolExecutor} decides on how many
    422 threads should be alive at any given time.
    423 </p>
    424 <h4>How many threads should you create?</h4>
    425 <p>
    426 Although from a software level, your code has the ability to create hundreds of
    427 threads, doing so can create performance issues. CPUs really only have the
    428 ability to handle a small number of threads in parallel; everything above that
    429 runs<a
    430 href="https://www.youtube.com/watch?v=NwFXVsM15Co&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=9">
    431 into priority and scheduling issues</a>. As such, its important to only create
    432 as many threads as your workload needs.
    433 </p>
    434 <p>
    435 Practically speaking, theres a number of variables responsible for this, but
    436 picking a value (like 4, for starters), and testing it with <a
    437 href={@docRoot}studio/profile/systrace-commandline.html>Systrace</a> is as
    438 solid a strategy as any other. You can use trial-and-error to discover the
    439 minimum number of threads you can use without running into problems.
    440 </p>
    441 <p>
    442 Another consideration in deciding on how many threads to have is that threads
    443 arent free: they take up memory. Each thread costs a minimum of 64k of memory.
    444 This adds up quickly across the many apps installed on a device, especially in
    445 situations where the call stacks grow significantly.
    446 </p>
    447 <p>
    448 Many system processes and third-party libraries often spin up their own
    449 threadpools. If your app can reuse an existing threadpool, this reuse may help
    450 performance by reducing contention for memory and processing resources.
    451 </p>
    452 
    453 
    454