Home | History | Annotate | Download | only in articles
      1 page.title=Managing Your App's Memory
      2 page.tags=ram,low memory,OutOfMemoryError,onTrimMemory
      3 page.article=true
      4 @jd:body
      5 
      6 
      7 <div id="tb-wrapper">
      8 <div id="tb">
      9 
     10 <h2>In this document</h2>
     11 <ol class="nolist">
     12   <li><a href="#Android">How Android Manages Memory</a>
     13     <ol>
     14       <li><a href="#SharingRAM">Sharing Memory</a></li>
     15       <li><a href="#AllocatingRAM">Allocating and Reclaiming App Memory</a></li>
     16       <li><a href="#RestrictingMemory">Restricting App Memory</a></li>
     17       <li><a href="#SwitchingApps">Switching Apps</a></li>
     18     </ol>
     19   </li>
     20   <li><a href="#YourApp">How Your App Should Manage Memory</a>
     21     <ol>
     22       <li><a href="#Services">Use services sparingly</a></li>
     23       <li><a href="#ReleaseMemoryAsUiGone">Release memory when your user interface becomes hidden</a></li>
     24       <li><a href="#ReleaseMemoryAsTight">Release memory as memory becomes tight</a></li>
     25       <li><a href="#CheckHowMuchMemory">Check how much memory you should use</a></li>
     26       <li><a href="#Bitmaps">Avoid wasting memory with bitmaps</a></li>
     27       <li><a href="#DataContainers">Use optimized data containers</a></li>
     28       <li><a href="#Overhead">Be aware of memory overhead</a></li>
     29       <li><a href="#Abstractions">Be careful with code abstractions</a></li>
     30       <li><a href="#NanoProto">Use nano protobufs for serialized data</a></li>
     31       <li><a href="#DependencyInjection">Avoid dependency injection frameworks</a></li>
     32       <li><a href="#ExternalLibs">Be careful about using external libraries</a></li>
     33       <li><a href="#OverallPerf">Optimize overall performance</a></li>
     34       <li><a href="#Proguard">Use ProGuard to strip out any unneeded code</a></li>
     35       <li><a href="#Zipalign">Use zipalign on your final APK</a></li>
     36       <li><a href="#AnalyzeRam">Analyze your RAM usage</a></li>
     37       <li><a href="#MultipleProcesses">Use multiple processes</a></li>
     38     </ol>
     39   </li>
     40 </ol>
     41 <h2>See Also</h2>
     42 <ul>
     43   <li><a href="{@docRoot}tools/debugging/debugging-memory.html">Investigating Your RAM Usage</a>
     44   </li>
     45 </ul>
     46 
     47 </div>
     48 </div>
     49 
     50 
     51 <p>Random-access memory (RAM) is a valuable resource in any software development environment, but
     52 it's even more valuable on a mobile operating system where physical memory is often constrained.
     53 Although Android's Dalvik virtual machine performs routine garbage collection, this doesn't allow
     54 you to ignore when and where your app allocates and releases memory.</p>
     55 
     56 <p>In order for the garbage collector to reclaim memory from your app, you need to avoid
     57 introducing memory leaks (usually caused by holding onto object references in global members) and
     58 release any {@link java.lang.ref.Reference} objects at the appropriate time (as defined by
     59 lifecycle callbacks discussed further below). For most apps, the Dalvik garbage collector takes
     60 care of the rest: the system reclaims your memory allocations when the corresponding objects leave
     61 the scope of your app's active threads.</p>
     62 
     63 <p>This document explains how Android manages app processes and memory allocation, and how you can
     64 proactively reduce memory usage while developing for Android. For more information about general
     65 practices to clean up your resources when programming in Java, refer to other books or online
     66 documentation about managing resource references. If youre looking for information about how to
     67 analyze your apps memory once youve already built it, read <a
     68 href="{@docRoot}tools/debugging/debugging-memory.html">Investigating Your RAM Usage</a>.</p>
     69 
     70 
     71 
     72 
     73 <h2 id="Android">How Android Manages Memory</h2>
     74 
     75 <p>Android does not offer swap space for memory, but it does use <a href=
     76 "http://en.wikipedia.org/wiki/Paging" class="external-link">paging</a> and <a href=
     77 "http://en.wikipedia.org/wiki/Memory-mapped_files" class="external-link">memory-mapping</a>
     78 (mmapping) to manage memory. This means that any memory you modify&mdash;whether by allocating
     79 new objects or touching mmapped pages&mdash;remains resident in RAM and cannot be paged out.
     80 So the only way to completely release memory from your app is to release object references you may
     81 be holding, making the memory available to the garbage collector. That is with one exception:
     82 any files mmapped in without modification, such as code, can be paged out of RAM if the system
     83 wants to use that memory elsewhere.</p>
     84 
     85 
     86 <h3 id="SharingRAM">Sharing Memory</h3>
     87 
     88 <p>In order to fit everything it needs in RAM, Android tries to share RAM pages across processes. It
     89 can do so in the following ways:</p>
     90 <ul>
     91 <li>Each app process is forked from an existing process called Zygote.
     92 The Zygote process starts when the system boots and loads common framework code and resources
     93 (such as activity themes). To start a new app process, the system forks the Zygote process then
     94 loads and runs the app's code in the new process. This allows most of the RAM pages allocated for
     95 framework code and resources to be shared across all app processes.</li>
     96 
     97 <li>Most static data is mmapped into a process. This not only allows that same data to be shared
     98 between processes but also allows it to be paged out when needed. Example static data include:
     99 Dalvik code (by placing it in a pre-linked {@code .odex} file for direct mmapping), app resources
    100 (by designing the resource table to be a structure that can be mmapped and by aligning the zip
    101 entries of the APK), and traditional project elements like native code in {@code .so} files.</li>
    102 
    103 <li>In many places, Android shares the same dynamic RAM across processes using explicitly allocated
    104 shared memory regions (either with ashmem or gralloc). For example, window surfaces use shared
    105 memory between the app and screen compositor, and cursor buffers use shared memory between the
    106 content provider and client.</li>
    107 </ul>
    108 
    109 <p>Due to the extensive use of shared memory, determining how much memory your app is using requires
    110 care. Techniques to properly determine your app's memory use are discussed in <a
    111 href="{@docRoot}tools/debugging/debugging-memory.html">Investigating Your RAM Usage</a>.</p>
    112 
    113 
    114 <h3 id="AllocatingRAM">Allocating and Reclaiming App Memory</h3>
    115 
    116 <p>Here are some facts about how Android allocates then reclaims memory from your app:</p>
    117 
    118 <ul>
    119 <li>The Dalvik heap for each process is constrained to a single virtual memory range. This defines
    120 the logical heap size, which can grow as it needs to (but only up to a limit that the system defines
    121 for each app).</li>
    122 
    123 <li>The logical size of the heap is not the same as the amount of physical memory used by the heap.
    124 When inspecting your app's heap, Android computes a value called the Proportional Set Size (PSS),
    125 which accounts for both dirty and clean pages that are shared with other processes&mdash;but only in an
    126 amount that's proportional to how many apps share that RAM. This (PSS) total is what the system
    127 considers to be your physical memory footprint. For more information about PSS, see the <a
    128 href="{@docRoot}tools/debugging/debugging-memory.html#ViewingAllocations">Investigating Your
    129 RAM Usage</a> guide.</li>
    130 
    131 <li>The Dalvik heap does not compact the logical size of the heap, meaning that Android does not
    132 defragment the heap to close up space. Android can only shrink the logical heap size when there
    133 is unused space at the end of the heap. But this doesn't mean the physical memory used by the heap
    134 can't shrink. After garbage collection, Dalvik walks the heap and finds unused pages, then returns
    135 those pages to the kernel using madvise. So, paired allocations and deallocations of large
    136 chunks should result in reclaiming all (or nearly all) the physical memory used. However,
    137 reclaiming memory from small allocations can be much less efficient because the page used
    138 for a small allocation may still be shared with something else that has not yet been freed.</li>
    139 </ul>
    140 
    141 
    142 <h3 id="RestrictingMemory">Restricting App Memory</h3>
    143 
    144 <p>To maintain a functional multi-tasking environment, Android sets a hard limit on the heap size
    145 for each app. The exact heap size limit varies between devices based on how much RAM the device
    146 has available overall. If your app has reached the heap capacity and tries to allocate more
    147 memory, it will receive an {@link java.lang.OutOfMemoryError}.</p>
    148 
    149 <p>In some cases, you might want to query the system to determine exactly how much heap space you
    150 have available on the current device&mdash;for example, to determine how much data is safe to keep in a
    151 cache. You can query the system for this figure by calling {@link
    152 android.app.ActivityManager#getMemoryClass()}. This returns an integer indicating the number of
    153 megabytes available for your app's heap. This is discussed further below, under
    154 <a href="#CheckHowMuchMemory">Check how much memory you should use</a>.</p>
    155 
    156 
    157 <h3 id="SwitchingApps">Switching Apps</h3>
    158 
    159 <p>Instead of using swap space when the user switches between apps, Android keeps processes that
    160 are not hosting a foreground ("user visible") app component in a least-recently used (LRU) cache.
    161 For example, when the user first launches an app, a process is created for it, but when the user
    162 leaves the app, that process does <em>not</em> quit. The system keeps the process cached, so if
    163 the user later returns to the app, the process is reused for faster app switching.</p>
    164 
    165 <p>If your app has a cached process and it retains memory that it currently does not need,
    166 then your app&mdash;even while the user is not using it&mdash;is constraining the system's
    167 overall performance. So, as the system runs low on memory, it may kill processes in the LRU cache
    168 beginning with the process least recently used, but also giving some consideration toward
    169 which processes are most memory intensive. To keep your process cached as long as possible, follow
    170 the advice in the following sections about when to release your references.</p>
    171 
    172 <p>More information about how processes are cached while not running in the foreground and how
    173 Android decides which ones
    174 can be killed is available in the <a href="{@docRoot}guide/components/processes-and-threads.html"
    175 >Processes and Threads</a> guide.</p>
    176 
    177 
    178 
    179 
    180 <h2 id="YourApp">How Your App Should Manage Memory</h2>
    181 
    182 <p>You should consider RAM constraints throughout all phases of development, including during app
    183 design (before you begin development). There are many
    184 ways you can design and write code that lead to more efficient results, through aggregation of the
    185 same techniques applied over and over.</p>
    186 
    187 <p>You should apply the following techniques while designing and implementing your app to make it
    188 more memory efficient.</p>
    189 
    190 
    191 <h3 id="Services">Use services sparingly</h3>
    192 
    193 <p>If your app needs a <a href="{@docRoot}guide/components/services.html">service</a>
    194 to perform work in the background, do not keep it running unless
    195 it's actively performing a job. Also be careful to never leak your service by failing to stop it
    196 when its work is done.</p>
    197 
    198 <p>When you start a service, the system prefers to always keep the process for that service
    199 running. This makes the process very expensive because the RAM used by the service cant be used by
    200 anything else or paged out. This reduces the number of cached processes that the system can keep in
    201 the LRU cache, making app switching less efficient. It can even lead to thrashing in the system
    202 when memory is tight and the system cant maintain enough processes to host all the services
    203 currently running.</p>
    204 
    205 <p>The best way to limit the lifespan of your service is to use an {@link
    206 android.app.IntentService}, which finishes
    207 itself as soon as it's done handling the intent that started it. For more information, read
    208 <a href="{@docRoot}training/run-background-service/index.html">Running in a Background Service</a>
    209 .</p>
    210 
    211 <p>Leaving a service running when its not needed is <strong>one of the worst memory-management
    212 mistakes</strong> an Android app can make. So dont be greedy by keeping a service for your app
    213 running. Not only will it increase the risk of your app performing poorly due to RAM constraints,
    214 but users will discover such misbehaving apps and uninstall them.</p>
    215 
    216 
    217 <h3 id="ReleaseMemoryAsUiGone">Release memory when your user interface becomes hidden</h3>
    218 
    219 <p>When the user navigates to a different app and your UI is no longer visible, you should
    220 release any resources that are used by only your UI. Releasing UI resources at this time can
    221 significantly increase the system's capacity for cached processes, which has a direct impact on the
    222 quality of the user experience.</p>
    223 
    224 <p>To be notified when the user exits your UI, implement the {@link
    225 android.content.ComponentCallbacks2#onTrimMemory onTrimMemory()} callback in your {@link
    226 android.app.Activity} classes. You should use this
    227 method to listen for the {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN} level,
    228 which indicates your UI is now hidden from view and you should free resources that only your UI
    229 uses.</p>
    230 
    231 
    232 <p>Notice that your app receives the {@link android.content.ComponentCallbacks2#onTrimMemory
    233 onTrimMemory()} callback with {@link android.content.ComponentCallbacks2#TRIM_MEMORY_UI_HIDDEN}
    234 only when <em>all the UI components</em> of your app process become hidden from the user.
    235 This is distinct
    236 from the {@link android.app.Activity#onStop onStop()} callback, which is called when an {@link
    237 android.app.Activity} instance becomes hidden, which occurs even when the user moves to
    238 another activity in your app. So although you should implement {@link android.app.Activity#onStop
    239 onStop()} to release activity resources such as a network connection or to unregister broadcast
    240 receivers, you usually should not release your UI resources until you receive {@link
    241 android.content.ComponentCallbacks2#onTrimMemory onTrimMemory(TRIM_MEMORY_UI_HIDDEN)}. This ensures
    242 that if the user navigates <em>back</em> from another activity in your app, your UI resources are
    243 still available to resume the activity quickly.</p>
    244 
    245 
    246 
    247 <h3 id="ReleaseMemoryAsTight">Release memory as memory becomes tight</h3>
    248 
    249 <p>During any stage of your app's lifecycle, the {@link
    250 android.content.ComponentCallbacks2#onTrimMemory onTrimMemory()} callback also tells you when
    251 the overall device memory is getting low. You should respond by further releasing resources based
    252 on the following memory levels delivered by {@link android.content.ComponentCallbacks2#onTrimMemory
    253 onTrimMemory()}:</p>
    254 
    255 <ul>
    256 <li>{@link android.content.ComponentCallbacks2#TRIM_MEMORY_RUNNING_MODERATE}
    257 <p>Your app is running and not considered killable, but the device is running low on memory and the
    258 system is actively killing processes in the LRU cache.</p>
    259 </li>
    260 
    261 <li>{@link android.content.ComponentCallbacks2#TRIM_MEMORY_RUNNING_LOW}
    262 <p>Your app is running and not considered killable, but the device is running much lower on
    263 memory so you should release unused resources to improve system performance (which directly
    264 impacts your app's performance).</p>
    265 </li>
    266 
    267 <li>{@link android.content.ComponentCallbacks2#TRIM_MEMORY_RUNNING_CRITICAL}
    268 <p>Your app is still running, but the system has already killed most of the processes in the
    269 LRU cache, so you should release all non-critical resources now. If the system cannot reclaim
    270 sufficient amounts of RAM, it will clear all of the LRU cache and begin killing processes that
    271 the system prefers to keep alive, such as those hosting a running service.</p>
    272 </li>
    273 </ul>
    274 
    275 <p>Also, when your app process is currently cached, you may receive one of the following
    276 levels from {@link android.content.ComponentCallbacks2#onTrimMemory onTrimMemory()}:</p>
    277 <ul>
    278 <li>{@link android.content.ComponentCallbacks2#TRIM_MEMORY_BACKGROUND}
    279 <p>The system is running low on memory and your process is near the beginning of the LRU list.
    280 Although your app process is not at a high risk of being killed, the system may already be killing
    281 processes in the LRU cache. You should release resources that are easy to recover so your process
    282 will remain in the list and resume quickly when the user returns to your app.</p>
    283 </li>
    284 
    285 <li>{@link android.content.ComponentCallbacks2#TRIM_MEMORY_MODERATE}
    286 <p>The system is running low on memory and your process is near the middle of the LRU list. If the
    287 system becomes further constrained for memory, there's a chance your process will be killed.</p>
    288 </li>
    289 
    290 <li>{@link android.content.ComponentCallbacks2#TRIM_MEMORY_COMPLETE}
    291 <p>The system is running low on memory and your process is one of the first to be killed if the
    292 system does not recover memory now. You should release everything that's not critical to
    293 resuming your app state.</p>
    294 
    295 </li>
    296 </ul>
    297 
    298 <p>Because the {@link android.content.ComponentCallbacks2#onTrimMemory onTrimMemory()} callback was
    299 added in API level 14, you can use the {@link android.content.ComponentCallbacks#onLowMemory()}
    300 callback as a fallback for older versions, which is roughly equivalent to the {@link
    301 android.content.ComponentCallbacks2#TRIM_MEMORY_COMPLETE} event.</p>
    302 
    303 <p class="note"><strong>Note:</strong> When the system begins killing processes in the LRU cache,
    304 although it primarily works bottom-up, it does give some consideration to which processes are
    305 consuming more memory and will thus provide the system more memory gain if killed.
    306 So the less memory you consume while in the LRU list overall, the better your chances are
    307 to remain in the list and be able to quickly resume.</p>
    308 
    309 
    310 
    311 <h3 id="CheckHowMuchMemory">Check how much memory you should use</h3>
    312 
    313 <p>As mentioned earlier, each Android-powered device has a different amount of RAM available to the
    314 system and thus provides a different heap limit for each app. You can call {@link
    315 android.app.ActivityManager#getMemoryClass()} to get an estimate of your app's available heap in
    316 megabytes. If your app tries to allocate more memory than is available here, it will receive an
    317 {@link java.lang.OutOfMemoryError}.</p>
    318 
    319 <p>In very special situations, you can request a larger heap size by setting the <a
    320 href="{@docRoot}guide/topics/manifest/application-element.html#largeHeap">{@code largeHeap}</a>
    321 attribute to "true" in the manifest <a
    322 href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
    323 tag. If you do so, you can call {@link
    324 android.app.ActivityManager#getLargeMemoryClass()} to get an estimate of the large heap size.</p>
    325 
    326 <p>However, the ability to request a large heap is intended only for a small set of apps that can
    327 justify the need to consume more RAM (such as a large photo editing app). <strong>Never request a
    328 large heap simply because you've run out of memory</strong> and you need a quick fix&mdash;you
    329 should use it only when you know exactly where all your memory is being allocated and why it must
    330 be retained. Yet, even when you're confident your app can justify the large heap, you should avoid
    331 requesting it to whatever extent possible. Using the extra memory will increasingly be to the
    332 detriment of the overall user experience because garbage collection will take longer and system
    333 performance may be slower when task switching or performing other common operations.</p>
    334 
    335 <p>Additionally, the large heap size is not the same on all devices and, when running on
    336 devices that have limited RAM, the large heap size may be exactly the same as the regular heap
    337 size. So even if you do request the large heap size, you should call {@link
    338 android.app.ActivityManager#getMemoryClass()} to check the regular heap size and strive to always
    339 stay below that limit.</p>
    340 
    341 
    342 <h3 id="Bitmaps">Avoid wasting memory with bitmaps</h3>
    343 
    344 <p>When you load a bitmap, keep it in RAM only at the resolution you need for the current device's
    345 screen, scaling it down if the original bitmap is a higher resolution. Keep in mind that an
    346 increase in bitmap resolution results in a corresponding (increase<sup>2</sup>) in memory needed,
    347 because both the X and Y dimensions increase.</p>
    348 
    349 <p class="note"><strong>Note:</strong> On Android 2.3.x (API level 10) and below, bitmap objects
    350 always appear as the same size in your app heap regardless of the image resolution (the actual
    351 pixel data is stored separately in native memory). This makes it more difficult to debug the bitmap
    352 memory allocation because most heap analysis tools do not see the native allocation. However,
    353 beginning in Android 3.0 (API level 11), the bitmap pixel data is allocated in your app's Dalvik
    354 heap, improving garbage collection and debuggability. So if your app uses bitmaps and you're having
    355 trouble discovering why your app is using some memory on an older device, switch to a device
    356 running Android 3.0 or higher to debug it.</p>
    357 
    358 <p>For more tips about working with bitmaps, read <a
    359 href="{@docRoot}training/displaying-bitmaps/manage-memory.html">Managing Bitmap Memory</a>.</p>
    360 
    361 
    362 <h3 id="DataContainers">Use optimized data containers</h3>
    363 
    364 <p>Take advantage of optimized containers in the Android framework, such as {@link
    365 android.util.SparseArray}, {@link android.util.SparseBooleanArray}, and {@link
    366 android.support.v4.util.LongSparseArray}. The generic {@link java.util.HashMap}
    367 implementation can be quite memory
    368 inefficient because it needs a separate entry object for every mapping. Additionally, the {@link
    369 android.util.SparseArray} classes are more efficient because they avoid the system's need
    370 to <acronym title=
    371 "Automatic conversion from primitive types to object classes (such as int to Integer)"
    372 >autobox</acronym>
    373 the key and sometimes value (which creates yet another object or two per entry). And don't be
    374 afraid of dropping down to raw arrays when that makes sense.</p>
    375 
    376 
    377 
    378 <h3 id="Overhead">Be aware of memory overhead</h3>
    379 
    380 <p>Be knowledgeable about the cost and overhead of the language and libraries you are using, and
    381 keep this information in mind when you design your app, from start to finish. Often, things on the
    382 surface that look innocuous may in fact have a large amount of overhead. Examples include:</p>
    383 <ul>
    384 <li>Enums often require more than twice as much memory as static constants. You should strictly
    385 avoid using enums on Android.</li>
    386 
    387 <li>Every class in Java (including anonymous inner classes) uses about 500 bytes of code.</li>
    388 
    389 <li>Every class instance has 12-16 bytes of RAM overhead.</li>
    390 
    391 <li>Putting a single entry into a {@link java.util.HashMap} requires the allocation of an
    392 additional entry object that takes 32 bytes (see the previous section about <a
    393 href="#DataContainers">optimized data containers</a>).</li>
    394 </ul>
    395 
    396 <p>A few bytes here and there quickly add upapp designs that are class- or object-heavy will suffer
    397 from this overhead. That can leave you in the difficult position of looking at a heap analysis and
    398 realizing your problem is a lot of small objects using up your RAM.</p>
    399 
    400 
    401 <h3 id="Abstractions">Be careful with code abstractions</h3>
    402 
    403 <p>Often, developers use abstractions simply as a "good programming practice," because abstractions
    404 can improve code flexibility and maintenance. However, abstractions come at a significant cost:
    405 generally they require a fair amount more code that needs to be executed, requiring more time and
    406 more RAM for that code to be mapped into memory. So if your abstractions aren't supplying a
    407 significant benefit, you should avoid them.</p>
    408 
    409 
    410 <h3 id="NanoProto">Use nano protobufs for serialized data</h3>
    411 
    412 <p><a href="https://developers.google.com/protocol-buffers/docs/overview">Protocol
    413 buffers</a> are a language-neutral, platform-neutral, extensible mechanism designed by Google for
    414 serializing structured data&mdash;think XML, but smaller, faster, and simpler. If you decide to use
    415 protobufs for your data, you should always use nano protobufs in your client-side code. Regular
    416 protobufs generate extremely verbose code, which will cause many kinds of problems in your app:
    417 increased RAM use, significant APK size increase, slower execution, and quickly hitting the DEX
    418 symbol limit.</p>
    419 
    420 <p>For more information, see the "Nano version" section in the <a
    421 href="https://android.googlesource.com/platform/external/protobuf/+/master/java/README.txt"
    422 class="external-link">protobuf readme</a>.</p>
    423 
    424 
    425 
    426 <h3 id="DependencyInjection">Avoid dependency injection frameworks</h3>
    427 
    428 <p>Using a dependency injection framework such as <a
    429 href="https://code.google.com/p/google-guice/" class="external-link">Guice</a> or
    430 <a href="https://github.com/roboguice/roboguice" class="external-link">RoboGuice</a> may be
    431 attractive because they can simplify the code you write and provide an adaptive environment
    432 that's useful for testing and other configuration changes. However, these frameworks tend to perform
    433 a lot of process initialization by scanning your code for annotations, which can require significant
    434 amounts of your code to be mapped into RAM even though you don't need it. These mapped pages are
    435 allocated into clean memory so Android can drop them, but that won't happen until the pages have
    436 been left in memory for a long period of time.</p>
    437 
    438 
    439 <h3 id="ExternalLibs">Be careful about using external libraries</h3>
    440 
    441 <p>External library code is often not written for mobile environments and can be inefficient when used
    442 for work on a mobile client. At the very least, when you decide to use an external library, you
    443 should assume you are taking on a significant porting and maintenance burden to optimize the
    444 library for mobile. Plan for that work up-front and analyze the library in terms of code size and
    445 RAM footprint before deciding to use it at all.</p>
    446 
    447 <p>Even libraries supposedly designed for use on Android are potentially dangerous because each
    448 library may do things differently. For example, one library may use nano protobufs while another
    449 uses micro protobufs. Now you have two different protobuf implementations in your app. This can and
    450 will also happen with different implementations of logging, analytics, image loading frameworks,
    451 caching, and all kinds of other things you don't expect. <a
    452 href="{@docRoot}tools/help/proguard.html">ProGuard</a> won't save you here because these
    453 will all be lower-level dependencies that are required by the features for which you want the
    454 library. This becomes especially problematic when you use an {@link android.app.Activity}
    455 subclass from a library (which
    456 will tend to have wide swaths of dependencies), when libraries use reflection (which is common and
    457 means you need to spend a lot of time manually tweaking ProGuard to get it to work), and so on.</p>
    458 
    459 <p>Also be careful not to fall into the trap of using a shared library for one or two features out of
    460 dozens of other things it does; you don't want to pull in a large amount of code and overhead that
    461 you don't even use. At the end of the day, if there isn't an existing implementation that is a
    462 strong match for what you need to do, it may be best if you create your own implementation.</p>
    463 
    464 
    465 <h3 id="OverallPerf">Optimize overall performance</h3>
    466 
    467 <p>A variety of information about optimizing your app's overall performance is available
    468 in other documents listed in <a href="{@docRoot}training/best-performance.html">Best Practices
    469 for Performance</a>. Many of these documents include optimizations tips for CPU performance, but
    470 many of these tips also help optimize your app's memory use, such as by reducing the number of
    471 layout objects required by your UI.</p>
    472 
    473 <p>You should also read about <a href="{@docRoot}tools/debugging/debugging-ui.html">optimizing
    474 your UI</a> with the layout debugging tools and take advantage of
    475 the optimization suggestions provided by the <a
    476 href="{@docRoot}tools/debugging/improving-w-lint.html">lint tool</a>.</p>
    477 
    478 
    479 <h3 id="Proguard">Use ProGuard to strip out any unneeded code</h3>
    480 
    481 <p>The <a href="{@docRoot}tools/help/proguard.html">ProGuard</a> tool shrinks,
    482 optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and
    483 methods with semantically obscure names. Using ProGuard can make your code more compact, requiring
    484 fewer RAM pages to be mapped.</p>
    485 
    486 
    487 <h3 id="Zipalign">Use zipalign on your final APK</h3>
    488 
    489 <p>If you do any post-processing of an APK generated by a build system (including signing it
    490 with your final production certificate), then you must run <a
    491 href="{@docRoot}tools/help/zipalign.html">zipalign</a> on it to have it re-aligned.
    492 Failing to do so can cause your app to require significantly more RAM, because things like
    493 resources can no longer be mmapped from the APK.</p>
    494 
    495 <p class="note"><strong>Note:</strong> Google Play Store does not accept APK files that
    496 are not zipaligned.</p>
    497 
    498 
    499 <h3 id="AnalyzeRam">Analyze your RAM usage</h3>
    500 
    501 <p>Once you achieve a relatively stable build, begin analyzing how much RAM your app is using
    502 throughout all stages of its lifecycle. For information about how to analyze your app, read <a
    503 href="{@docRoot}tools/debugging/debugging-memory.html">Investigating Your RAM Usage</a>.</p>
    504 
    505 
    506 
    507 
    508 <h3 id="MultipleProcesses">Use multiple processes</h3>
    509 
    510 <p>If it's appropriate for your app, an advanced technique that may help you manage your app's
    511 memory is dividing components of your app into multiple processes. This technique must always be
    512 used carefully and <strong>most apps should not run multiple processes</strong>, as it can easily
    513 increase&mdash;rather than decrease&mdash;your RAM footprint if done incorrectly. It is primarily
    514 useful to apps that may run significant work in the background as well as the foreground and can
    515 manage those operations separately.</p>
    516 
    517 
    518 <p>An example of when multiple processes may be appropriate is when building a music player that
    519 plays music from a service for long period of time. If
    520 the entire app runs in one process, then many of the allocations performed for its activity UI must
    521 be kept around as long as it is playing music, even if the user is currently in another app and the
    522 service is controlling the playback. An app like this may be split into two process: one for its
    523 UI, and the other for the work that continues running in the background service.</p>
    524 
    525 <p>You can specify a separate process for each app component by declaring the <a href=
    526 "{@docRoot}guide/topics/manifest/service-element.html#proc">{@code android:process}</a> attribute
    527 for each component in the manifest file. For example, you can specify that your service should run
    528 in a process separate from your app's main process by declaring a new process named "background"
    529 (but you can name the process anything you like):</p>
    530 
    531 <pre>
    532 &lt;service android:name=".PlaybackService"
    533          android:process=":background" />
    534 </pre>
    535 
    536 <p>Your process name should begin with a colon (':') to ensure that the process remains private to
    537 your app.</p>
    538 
    539 <p>Before you decide to create a new process, you need to understand the memory implications.
    540 To illustrate the consequences of each process, consider that an empty process doing basically
    541 nothing has an extra memory footprint of about 1.4MB, as shown by the memory information
    542 dump below.</p>
    543 
    544 <pre class="no-pretty-print">
    545 adb shell dumpsys meminfo com.example.android.apis:empty
    546 
    547 ** MEMINFO in pid 10172 [com.example.android.apis:empty] **
    548                 Pss     Pss  Shared Private  Shared Private    Heap    Heap    Heap
    549               Total   Clean   Dirty   Dirty   Clean   Clean    Size   Alloc    Free
    550              ------  ------  ------  ------  ------  ------  ------  ------  ------
    551   Native Heap     0       0       0       0       0       0    1864    1800      63
    552   Dalvik Heap   764       0    5228     316       0       0    5584    5499      85
    553  Dalvik Other   619       0    3784     448       0       0
    554         Stack    28       0       8      28       0       0
    555     Other dev     4       0      12       0       0       4
    556      .so mmap   287       0    2840     212     972       0
    557     .apk mmap    54       0       0       0     136       0
    558     .dex mmap   250     148       0       0    3704     148
    559    Other mmap     8       0       8       8      20       0
    560       Unknown   403       0     600     380       0       0
    561         TOTAL  2417     148   12480    1392    4832     152    7448    7299     148
    562 </pre>
    563 
    564 <p class="note"><strong>Note:</strong> More information about how to read this output is provided
    565 in <a href="{@docRoot}tools/debugging/debugging-memory.html#ViewingAllocations">Investigating
    566 Your RAM Usage</a>. The key data here is the <em>Private Dirty</em> and <em>Private
    567 Clean</em> memory, which shows that this process is using almost 1.4MB of non-pageable RAM
    568 (distributed across the Dalvik heap, native allocations, book-keeping, and library-loading),
    569 and another 150K of RAM for code that has been mapped in to execute.</p>
    570 
    571 <p>This memory footprint for an empty process is fairly significant and it can quickly
    572 grow as you start doing work in that process. For
    573 example, here is the memory use of a process that is created only to show an activity with some
    574 text in it:</p>
    575 
    576 <pre class="no-pretty-print">
    577 ** MEMINFO in pid 10226 [com.example.android.helloactivity] **
    578                 Pss     Pss  Shared Private  Shared Private    Heap    Heap    Heap
    579               Total   Clean   Dirty   Dirty   Clean   Clean    Size   Alloc    Free
    580              ------  ------  ------  ------  ------  ------  ------  ------  ------
    581   Native Heap     0       0       0       0       0       0    3000    2951      48
    582   Dalvik Heap  1074       0    4928     776       0       0    5744    5658      86
    583  Dalvik Other   802       0    3612     664       0       0
    584         Stack    28       0       8      28       0       0
    585        Ashmem     6       0      16       0       0       0
    586     Other dev   108       0      24     104       0       4
    587      .so mmap  2166       0    2824    1828    3756       0
    588     .apk mmap    48       0       0       0     632       0
    589     .ttf mmap     3       0       0       0      24       0
    590     .dex mmap   292       4       0       0    5672       4
    591    Other mmap    10       0       8       8      68       0
    592       Unknown   632       0     412     624       0       0
    593         TOTAL  5169       4   11832    4032   10152       8    8744    8609     134
    594 </pre>
    595 
    596 <p>The process has now almost tripled in size, to 4MB, simply by showing some text in the UI. This
    597 leads to an important conclusion: If you are going to split your app into multiple processes, only
    598 one process should be responsible for UI. Other processes should avoid any UI, as this will quickly
    599 increase the RAM required by the process (especially once you start loading bitmap assets and other
    600 resources). It may then be hard or impossible to reduce the memory usage once the UI is drawn.</p>
    601 
    602 <p>Additionally, when running more than one process, it's more important than ever that you keep your
    603 code as lean as possible, because any unnecessary RAM overhead for common implementations are now
    604 replicated in each process. For example, if you are using enums (though <a
    605 href="#Overhead">you should not use enums</a>), all of
    606 the RAM needed to create and initialize those constants is duplicated in each process, and any
    607 abstractions you have with adapters and temporaries or other overhead will likewise be replicated.</p>
    608 
    609 <p>Another concern with multiple processes is the dependencies that exist between them. For example,
    610 if your app has a content provider that you have running in the default process which also hosts
    611 your UI, then code in a background process that uses that content provider will also require that
    612 your UI process remain in RAM. If your goal is to have a background process that can run
    613 independently of a heavy-weight UI process, it can't have dependencies on content providers or
    614 services that execute in the UI process.</p>
    615 
    616 
    617 
    618 
    619 
    620 
    621 
    622 
    623 
    624 
    625 <!-- THE FOLLOWING IS OVERWHELMING AND NOT NECESSARY FOR MOST APPS, LEAVING OUT FOR NOW
    626 
    627 
    628 <p>You can examine the dependencies between your processes with the command:</p>
    629 
    630 <pre class="no-pretty-print">
    631 adb shell dumpsys activity
    632 </pre>
    633 
    634 <p>This dumps various information about the Activity Manager's state, ending with a list of all
    635 processes in their memory management order, including the reason each process is at its given
    636 level. For example, below is a dump with the Music app in the foreground.</p>
    637 
    638 <pre class="no-pretty-print">
    639 ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)
    640   Process LRU list (sorted by oom_adj):
    641     PERS # 4: adj=sys  /F  trm= 0 20674:system/1000 (fixed)
    642     PERS #39: adj=pers /F  trm= 0 20964:com.android.nfc/1027 (fixed)
    643     PERS # 2: adj=pers /F  trm= 0 20959:com.android.phone/1001 (fixed)
    644     PERS # 1: adj=pers /F  trm= 0 20779:com.android.systemui/u0a10057 (fixed)
    645     Proc #11: adj=fore /FA trm= 0 8663:com.google.android.music:ui/u0a10043 (top-activity)
    646     Proc #10: adj=fore /F  trm= 0 30881:com.google.android.music:main/u0a10043 (provider)
    647         com.google.android.music/.store.MusicContentProvider<=Proc{8663:com.google.android.music:ui/u0a10043}
    648     Proc # 6: adj=fore /F  trm= 0 21014:com.google.process.gapps/u0a10023 (provider)
    649         com.google.android.gsf/.settings.GoogleSettingsProvider<=Proc{20935:com.google.process.location/u0a10023}
    650     Proc #38: adj=vis  /F  trm= 0 21028:com.android.nfc:handover/1027 (service)
    651         com.android.nfc/.handover.HandoverService<=Proc{20964:com.android.nfc/1027}
    652     Proc # 7: adj=vis  /B  trm= 0 20935:com.google.process.location/u0a10023 (service)
    653         com.google.android.location/.GeocodeService<=Proc{20674:system/1000}
    654     Proc # 3: adj=vis  /F  trm= 0 21225:com.android.bluetooth/1002 (service)
    655         com.android.bluetooth/.hfp.HeadsetService<=Proc{20674:system/1000}
    656     Proc # 0: adj=vis  /F  trm= 0 20908:com.google.android.inputmethod.latin/u0a10035 (service)
    657         com.google.android.inputmethod.latin/com.android.inputmethod.latin.LatinIME<=Proc{20674:system/1000}
    658     Proc #34: adj=svc  /B  trm= 0 16765:com.google.android.apps.currents/u0a10012 (started-services)
    659     Proc #14: adj=svc  /B  trm= 0 21148:com.google.android.gms/u0a10023 (started-services)
    660     Proc #12: adj=home /B  trm= 0 20989:com.android.launcher/u0a10036 (home)
    661     Proc #37: adj=svcb /B  trm= 0 15194:com.google.android.apps.googlevoice/u0a10089 (started-services)
    662     Proc #17: adj=svcb /B  trm= 0 24537:android.process.media/u0a10016 (started-services)
    663     Proc #35: adj=bak  /B  trm= 0 16087:com.android.defcontainer/u0a10013 (service)
    664         com.android.defcontainer/.DefaultContainerService<=Proc{16050:com.android.settings/1000}
    665     Proc #16: adj=bak  /B  trm= 0 7334:com.google.android.gm/u0a10022 (bg-act)
    666     Proc #15: adj=bak  /B  trm= 0 22499:com.google.android.googlequicksearchbox/u0a10060 (bg-act)
    667     Proc # 9: adj=bak  /B  trm= 0 20856:com.google.android.gsf.login/u0a10023 (bg-empty)
    668     Proc #26: adj=bak+1/B  trm= 0 9923:com.android.mms/u0a10042 (bg-act)
    669     Proc #23: adj=bak+1/B  trm= 0 16721:com.android.chrome/u0a10010 (bg-act)
    670     Proc #22: adj=bak+1/B  trm= 0 17596:com.android.chrome:sandboxed_process0/u0a10010i33 (service)
    671         com.android.chrome/org.chromium.content.app.SandboxedProcessService0<=Proc{16721:com.android.chrome/u0a10010}
    672     Proc #19: adj=bak+1/B  trm= 0 17442:com.google.android.youtube/u0a10067 (bg-services)
    673     Proc #18: adj=bak+2/B  trm= 0 16740:com.google.android.apps.plus/u0a10052 (bg-empty)
    674     Proc #13: adj=bak+2/B  trm= 0 7707:com.android.musicfx/u0a10044 (bg-empty)
    675     Proc #36: adj=bak+3/B  trm= 0 16050:com.android.settings/1000 (bg-act)
    676     Proc #33: adj=bak+3/B  trm= 0 16863:com.android.dialer/u0a10015 (bg-act)
    677 </pre>
    678 
    679 
    680 <p class="note"><strong>Note:</strong> The exact details of what is shown here will vary across
    681 platform versions as process management policies are tweaked and improved.</p>
    682 
    683 
    684 <p>Details on the highlighted sections are:</p>
    685 
    686 <ol>
    687 <li>Foreground app: This is the current app running in the foreground -- it is in the "fore" memory
    688 class because it is the top activity on the activity stack.</li>
    689 
    690 <li>Persistent processes: These are processes that are part of the core system that must always be
    691 running.</li>
    692 
    693 <li>Dependent process: This shows how the Music app is using two processes. Its UI process has a
    694 dependency on the "main" process (through a content provider). So while the UI process is in use,
    695 the main process must also be kept around. This means the app's memory footprint is actually the
    696 sum of both processes. You will have this kind of connection on a content provider any time you
    697 have active calls into it or have unclosed cursors or file streams that came from it.</li>
    698 
    699 <li>Visible processes: These are processes that count in some way as "visible" to the user. This
    700 generally means that it is either something the user can literally see (such as a process hosting a
    701 paused but visible activity that is behind a non-full-screen dialog) or is something the user might
    702 notice if the process disappeared (such as a foreground service playing music). You should be
    703 certain that any process you have running at the "visible" level is indeed critical to the user,
    704 because they are very expensive to the overall RAM load.</li>
    705 
    706 <li>Service processes: These are processes running long-term jobs in a service. This level of the
    707 list is the start of less-critical processes, which the system has some freedom to kill if RAM is
    708 needed elsewhere. These services are still quite expensive because they can be killed only
    709 temporarily and the system tries to keep them running whenever possible.</li>
    710 
    711 <li>Home process: A special slot for the process that hosts the current Home activity, to try to
    712 prevent it from being killed as much as possible. Killing this process is much more damaging to the
    713 user experience than killing other cached processes, because so much user interaction goes through
    714 home.</li>
    715 
    716 <li>Secondary service processes: These are services that have been running for a relatively long time
    717 and so should be killed more aggressively when RAM is needed elsewhere.</li>
    718 
    719 <li>Cached processes: These are cached processes held in the LRU cache, which allow for fast app
    720 switching and component launching. These processes are not required and the system will kill them
    721 as needed to reclaim memory. You will often see a process hosting a running service herethis is
    722 part of a platform policy of allowing very long-running services to drop down into the LRU list and
    723 eventually be killed. If the service should continue running (as defined by the {@link
    724 android.app.Service#onStartCommand onStartCommand()} return value, such as {@link
    725 android.app.Service#START_STICKY}), the the system eventually restarts it. This avoids issues with
    726 such services having memory leaks that over time reduce the number of regular cached processes that
    727 can be kept.</li>
    728 
    729 </ol>
    730 
    731 <p>This numbered list of processes is essentially the LRU list of processes that the framework
    732 provides to the kernel to help it determine which processes it should kill as it needs more RAM.
    733 The kernel's out of memory killer will generally begin from the bottom of this list, killing the
    734 last process and working its way up. It may not do it in exactly this order, as it can also take
    735 into consideration other factors such as the relative RAM footprint of processes to some degree.</p>
    736 
    737 <p>There are many other options you can use with the activity command to analyze further details of
    738 your app's state&mdash;use <code>adb shell dumpsys activity -h</code> for help on its use.</p>
    739 
    740 -->
    741