Clay Murphy | 2cf6611 | 2015-01-13 19:01:18 -0800 | [diff] [blame] | 1 | page.title=Configuring ART |
| 2 | @jd:body |
| 3 | |
| 4 | <!-- |
| 5 | Copyright 2014 The Android Open Source Project |
| 6 | |
| 7 | Licensed under the Apache License, Version 2.0 (the "License"); |
| 8 | you may not use this file except in compliance with the License. |
| 9 | You may obtain a copy of the License at |
| 10 | |
| 11 | http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | |
| 13 | Unless required by applicable law or agreed to in writing, software |
| 14 | distributed under the License is distributed on an "AS IS" BASIS, |
| 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 16 | See the License for the specific language governing permissions and |
| 17 | limitations under the License. |
| 18 | --> |
| 19 | |
| 20 | |
| 21 | <div id="qv-wrapper"> |
| 22 | <div id="qv"> |
| 23 | <h2 id="Contents">In this document</h2> |
| 24 | <ol id="auto-toc"> |
| 25 | </ol> |
| 26 | </div> |
| 27 | </div> |
| 28 | |
| 29 | <h2 id=introduction>Introduction</h2> |
| 30 | |
| 31 | <p>This document is intended to discuss how to configure ART and its compilation |
| 32 | options. Topics addressed here include configuration of pre-compilation of the |
| 33 | system image, dex2oat compilation options at first boot (and post-OTA), and how |
| 34 | to trade off system partition space, data partition space, and performance.</p> |
| 35 | |
| 36 | <p>See <a href="http://source.android.com/devices/tech/dalvik/index.html">ART |
| 37 | and Dalvik</a>, the <a |
| 38 | href="http://source.android.com/devices/tech/dalvik/dex-format.html">Dalvik |
| 39 | Executable format</a>, and the remaining pages on source.android.com to work |
| 40 | with ART. See <a |
| 41 | href="http://developer.android.com/guide/practices/verifying-apps-art.html">Verifying |
| 42 | App Behavior on the Android Runtime (ART)</a> to ensure your apps work |
| 43 | properly.</p> |
| 44 | |
| 45 | <h2 id=how_art_works>How ART works</h2> |
| 46 | |
| 47 | <p>ART is the new Android runtime for the Android 5.0 (Lollipop or L) release and |
| 48 | beyond. Dalvik is no longer available. </p> |
| 49 | |
| 50 | <p>Please note, this section merely summarizes ART’s configuration. For an |
| 51 | in-depth description, see the <a |
| 52 | href="https://www.google.com/events/io/io14videos/b750c8da-aebe-e311-b297-00155d5066d7">Android |
| 53 | runtime</a> presentation conducted at Google I/O 2014. </p> |
| 54 | |
| 55 | <p>ART uses ahead-of-time (AOT) compilation. This means that, at installation, dex |
| 56 | code is compiled to native code in OAT files, which replace Dalvik’s odex |
| 57 | files. This has several implications:</p> |
| 58 | |
| 59 | <ul> |
| 60 | <li> Performance is improved over Dalvik. There is also a commensurate improvement |
| 61 | in power consumption measured in the lab. |
| 62 | <li> There is no runtime code cache. The OAT files are mapped to memory (and are |
| 63 | thus page-able). The RAM memory footprint for OAT files might seem larger in |
| 64 | terms of Proportional Set Size (PSS, or the memory shared across processes |
| 65 | divided evenly between the processes). But because they are pageable we have |
| 66 | found the system impact is improved in terms of real memory pressure effects as |
| 67 | the Dalvik JIT cache was not pageable. |
| 68 | <li> Similar to preloaded classes in the zygote, ART attempts to pre-initialize a |
| 69 | set of classes at compile time. This creates a ‘boot.art’ file that comprises |
| 70 | an image of the compacted heap of pre-initialized classes and related objects. |
| 71 | This file is mapped into memory upon zygote startup. While this consumes |
| 72 | additional storage (typically 10MB), it speeds zygote startup and creates |
| 73 | opportunities for the system to swap out some preloaded classes under memory |
| 74 | pressure. This also contributes to improved <a |
| 75 | href="http://source.android.com/devices/low-ram.html">low-RAM</a> performance |
| 76 | for ART, since in Dalvik much of this class information would have |
| 77 | been stored in dirty pages in the linear alloc space. |
| 78 | <li> Dex file compilation uses a tool called dex2oat and takes more time than |
| 79 | dexopt. The increase in time varies, but 2-3x increases in compile time are not |
| 80 | unusual. For example, apps that typically take a second to install using dexopt |
| 81 | might take 2-3 seconds. |
| 82 | <li> OAT files are larger than odex files if full compilation is enabled. We discuss |
| 83 | options to mitigate this cost later in this document. |
| 84 | </ul> |
| 85 | |
| 86 | <h2 id=compilation_options>Compilation options</h2> |
| 87 | |
| 88 | <p>Dex file compilation takes more time than dexopt, which can be noticeable when |
| 89 | all of a user’s apps must be compiled during first boot (after factory reset or |
| 90 | after receiving an OTA). To reduce the amount of compilation needed, ART |
| 91 | supports the option of pre-optimizing libraries and applications in the system |
| 92 | partition. Including the pre-optimized dex files takes space in the system |
| 93 | image, so these options trade first boot time for system image size. Note that |
| 94 | OTAs are relatively infrequent and subsequent boot times should be the same |
| 95 | with or without pre-optimization.</p> |
| 96 | |
| 97 | <h3 id=undefined>WITH_DEXPREOPT</h3> |
| 98 | |
| 99 | <p>Pre-optimization is controlled by the build option |
| 100 | <code>WITH_DEXPREOPT</code>. Before the L release, this was enabled by default |
| 101 | in “user” builds. Starting in L, this option is opt-in and needs to be enabled |
| 102 | in the product configuration such as a device’s BoardConfig.mk file.</p> |
| 103 | |
| 104 | <p>Enabling <code>WITH_DEXPREOPT</code> causes everything in the system image to be |
| 105 | pre-optimized. If this makes the system image too large, additional options can |
| 106 | be specified to reduce the amount of pre-optimization. Note that all the |
| 107 | following build options with “PREOPT” in the name must have <code>WITH_DEXPREOPT</code> |
| 108 | enabled to work.</p> |
| 109 | |
| 110 | <p>Example usage (in product’s BoardConfig.mk):</p> |
| 111 | |
| 112 | <pre><code>WITH_DEXPREOPT := true</code></pre> |
| 113 | |
| 114 | <h3 id=dont_dexpreopt_prebuilts>DONT_DEXPREOPT_PREBUILTS</h3> |
| 115 | |
| 116 | <p>Enabling <code>DONT_DEXPREOPT_PREBUILTS</code> prevents the prebuilts from being |
| 117 | pre-optimized. These are apps that have <code>include $(BUILD_PREBUILT)</code> specified |
| 118 | in their Android.mk, such as Gmail. Skipping pre-optimization of prebuilt apps |
| 119 | that are likely to be updated via Google Play saves /system space but does add |
| 120 | to first boot time.</p> |
| 121 | |
| 122 | <p>Example usage (in product’s BoardConfig.mk):</p> |
| 123 | |
| 124 | <pre><code>WITH_DEXPREOPT := true |
| 125 | DONT_DEXPREOPT_PREBUILTS := true</code></pre> |
| 126 | |
| 127 | <h3 id=with_dexpreopt_boot_img_only>WITH_DEXPREOPT_BOOT_IMG_ONLY</h3> |
| 128 | |
| 129 | <p>Enabling <code>WITH_DEXPREOPT_BOOT_IMG_ONLY</code> only pre-optimizes the |
| 130 | boot image, which consists of boot.art with the image classes and boot.oat with |
| 131 | code for the boot classpath. Enabling this saves significant /system space but |
| 132 | means all apps will be optimized at first boot. Typically it is better to |
| 133 | selectively disable app pre-optimization via |
| 134 | <code>DONT_DEXPREOPT_PREBUILTS</code> or add-product-dex-preopt-module-config.</p> |
| 135 | |
| 136 | <p>Example usage (in product’s BoardConfig.mk):</p> |
| 137 | |
| 138 | <pre><code>WITH_DEXPREOPT := true |
| 139 | WITH_DEXPREOPT_BOOT_IMG_ONLY := true</code></pre> |
| 140 | |
| 141 | <h3 id=local_dex_preopt>LOCAL_DEX_PREOPT</h3> |
| 142 | |
| 143 | <p>Pre-optimization can also be enabled or disabled on an individual app basis by |
| 144 | specifying the <code>LOCAL_DEX_PREOPT</code> option in the module definition. |
| 145 | This can be useful for disabling pre-optimization of apps that may immediately |
| 146 | receive Google Play updates since the updates would render the pre-optimized |
| 147 | code in the system image obsolete. This is also useful to save space on major |
| 148 | version upgrade OTAs since users may already have newer versions of apps in the |
| 149 | data partition.</p> |
| 150 | |
| 151 | <p><code>LOCAL_DEX_PREOPT</code> supports the values ‘true’ or ‘false’ to |
| 152 | enable or disable pre-optimization respectively. In addition, ‘nostripping’ can |
| 153 | be specified if pre-optimization should not strip the classes.dex file from the |
| 154 | apk or jar file. Normally this file is stripped since it’s no longer needed |
| 155 | after pre-optimization, but this last option is necessary to allow third-party |
| 156 | APK signatures to remain valid.</p> |
| 157 | |
| 158 | <p>Example usage (in app’s Android.mk):</p> |
| 159 | |
| 160 | <pre><code>LOCAL_DEX_PREOPT := false</code></pre> |
| 161 | |
| 162 | <h3 id=product_dex_preopt_*>PRODUCT_DEX_PREOPT_*</h3> |
| 163 | |
| 164 | <p>Beginning post-L release in the Android Open Source Project (AOSP), a number of |
| 165 | flags have been added that give further control to how pre-optimization is |
| 166 | done. <code>PRODUCT_DEX_PREOPT_BOOT_FLAGS</code> passes options to dex2oat to control how |
| 167 | the boot image is compiled. It can be used to specify customized image classes |
| 168 | lists, compiled classes lists, and compiler filters, all of which are described |
| 169 | in later sections. Similarly, <code>PRODUCT_DEX_PREOPT_DEFAULT_FLAGS</code> |
| 170 | controls default flags to pass to dex2oat for compilation of everything besides |
| 171 | the boot image, namely jar and apk files.</p> |
| 172 | |
| 173 | <p><code>PRODUCT_DEX_PREOPT_MODULE_CONFIGS</code> provides the ability to pass |
| 174 | dex2oat options for a particular module and product configuration. It is set in |
| 175 | a product’s device.mk file by <code>$(call |
| 176 | add-product-dex-preopt-module-config,<modules>,<option>)</code> |
| 177 | where <modules> is a list of <code>LOCAL_MODULE</code> and |
| 178 | <code>LOCAL_PACKAGE</code> names for jar and apk files respectively. Through |
| 179 | this flag, it is possible to have fine-grained control of pre-optimization for |
| 180 | each dex file and a specific device. Such tuning allows /system space to be |
| 181 | maximally used to improve first boot time.</p> |
| 182 | |
| 183 | <p>Example usage (in product’s device.mk):</p> |
| 184 | |
| 185 | <pre><code>PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := --compiler-filter=interpret-only |
| 186 | $(call add-product-dex-preopt-module-config,services,--compiler-filter=space)</code></pre> |
| 187 | |
| 188 | <h2 id=preloaded_classes_list>Preloaded Classes List</h2> |
| 189 | |
| 190 | <p>The preloaded classes list is a list of classes the zygote will initialize on |
| 191 | startup. This saves each app from having to run these class initializers |
| 192 | separately, allowing them to start up faster and share pages in memory. The |
| 193 | preloaded classes list file is located at frameworks/base/preloaded-classes by |
| 194 | default, and it contains a list that is tuned for typical phone use. This may |
| 195 | be different for other devices, such as wearables, and should be tuned |
| 196 | accordingly. Be careful when tuning this since adding too many classes wastes |
| 197 | memory loading unused classes; meanwhile, adding too few forces each app to |
| 198 | have to have its own copy, again wasting memory.</p> |
| 199 | |
| 200 | <p>Example usage (in product’s device.mk):</p> |
| 201 | |
| 202 | <pre><code>PRODUCT_COPY_FILES += <filename>:system/etc/preloaded-classes</code></pre> |
| 203 | |
| 204 | <p class="note"><strong>Note:</strong> This line must be placed before |
| 205 | inheriting any product configuration makefiles that get the default one from |
| 206 | build/target/product/base.mk.</p> |
| 207 | |
| 208 | <h2 id=image_classes_list>Image Classes List</h2> |
| 209 | |
| 210 | <p>The image classes list is a list of classes that dex2oat initializes ahead of |
| 211 | time and stores in the boot.art file. This allows the zygote to load these |
| 212 | results out of the boot.art file on startup instead of running the initializers |
| 213 | for these classes itself during preloading. A key feature of this is that the |
| 214 | pages loaded from the image and shared between processes can be clean, allowing |
| 215 | them to be swapped out easily in low-memory situations. In L, by default the |
| 216 | image classes list uses the same list as the preloaded classes list. Beginning |
| 217 | post-L in AOSP, a custom image classes list can be specified using |
| 218 | <code>PRODUCT_DEX_PREOPT_BOOT_FLAGS</code>.</p> |
| 219 | |
| 220 | <p>Example usage (in product’s device.mk):</p> |
| 221 | |
| 222 | <pre><code>PRODUCT_DEX_PREOPT_BOOT_FLAGS += --image-classes=<filename></code></pre> |
| 223 | |
| 224 | <h2 id=compiled_classes_list>Compiled Classes List</h2> |
| 225 | |
| 226 | <p>In post-L AOSP, a subset of classes from the boot classpath can be specified to |
| 227 | be compiled during pre-optimization using the compiled classes list. This can |
| 228 | be a useful option for devices that are very tight on space and can’t fit the |
| 229 | entire pre-optimized boot image. However, note classes not specified by this |
| 230 | list will not be compiled - not even on the device - and must be interpreted, |
| 231 | potentially affecting runtime performance. By default, dex2oat will look for a |
| 232 | compiled classes list in $OUT/system/etc/compiled-classes, so a custom one can |
| 233 | be copied to that location by the device.mk. A particular file location can |
| 234 | also be specified using <code>PRODUCT_DEX_PREOPT_BOOT_FLAGS</code>.</p> |
| 235 | |
| 236 | <p>Example usage (in product’s device.mk):</p> |
| 237 | |
| 238 | <pre><code>PRODUCT_COPY_FILES += <filename>:system/etc/compiled-classes</code></pre> |
| 239 | |
| 240 | <p class="note"><strong>Note:</strong> This line must be placed before |
| 241 | inheriting any product configuration makefiles that get the default one from |
| 242 | build/target/product/base.mk.</p> |
| 243 | |
| 244 | <h2 id=compiler_filters>Compiler Filters</h2> |
| 245 | |
| 246 | <p>In L, dex2oat takes a variety of --compiler-filter options to control how it |
| 247 | compiles. Passing in a compiler filter flag for a particular app specifies how |
| 248 | it’s pre-optimized. Here’s a description of each available option:</p> |
| 249 | |
| 250 | <ul> |
| 251 | <li><em>everything</em> - compiles almost everything, excluding class initializers and some rare |
| 252 | methods that are too large to be represented by the compiler’s internal |
| 253 | representation. |
| 254 | <li><em>speed</em> - compiles most methods and maximizes runtime performance, which is the |
| 255 | default option. |
| 256 | <li><em>balanced</em> - attempts to get the best performance return on compilation investment. |
| 257 | <li><em>space</em> - compiles a limited number of methods, prioritizing storage space. |
| 258 | <li><em>interpret-only</em> - skips all compilation and relies on the interpreter to run code. |
| 259 | <li><em>verify-none</em> - special option that skips verification and compilation, should be used only |
| 260 | for trusted system code. |
| 261 | </ul> |
| 262 | |
| 263 | <h2 id=with_dexpreopt_pic>WITH_DEXPREOPT_PIC</h2> |
| 264 | |
| 265 | <p>In post-L AOSP, <code>WITH_DEXPREOPT_PIC</code> can be specified to enable |
| 266 | position-independent code (PIC). With this, compiled code from the image |
| 267 | doesn’t have to be relocated from /system into /data/dalvik-cache, saving space |
| 268 | in the data partition. However, there is a slight runtime impact because it |
| 269 | disables an optimization that takes advantage of position-dependent code. |
| 270 | Typically, devices wanting to save space in /data should enable PIC |
| 271 | compilation.</p> |
| 272 | |
| 273 | <p>Example usage (in product’s device.mk):</p> |
| 274 | |
| 275 | <pre><code>WITH_DEXPREOPT := true |
| 276 | WITH_DEXPREOPT_PIC := true</code></pre> |
| 277 | |
| 278 | <h2 id=with_art_small_mode>WITH_ART_SMALL_MODE</h2> |
| 279 | |
| 280 | <p>For devices with very limited space, <code>WITH_ART_SMALL_MODE</code> can be |
| 281 | enabled. This option compiles the boot classpath and nothing else, greatly |
| 282 | reducing first boot time since most compilation is skipped. It also saves on |
| 283 | storage because there is no compiled code for apps. However, this impacts |
| 284 | runtime performance since app code has to be interpreted. The impact is limited |
| 285 | since most performance sensitive code in the framework is still compiled, but |
| 286 | regressions may appear in benchmarking.</p> |
| 287 | |
| 288 | <p>Example usage (in product’s device.mk):</p> |
| 289 | |
| 290 | <pre><code>WITH_ART_SMALL_MODE := true</code></pre> |
| 291 | |
| 292 | <p>In future releases, this build option will be removed since it can be done with |
| 293 | this (in product’s device.mk):</p> |
| 294 | |
| 295 | <pre><code>PRODUCT_PROPERTY_OVERRIDES += \ |
| 296 | dalvik.vm.dex2oat-filter=interpret-only \ |
| 297 | dalvik.vm.image-dex2oat-filter=speed</code></pre> |
| 298 | |
| 299 | <h2 id=dalvik_vm_properties>dalvik.vm Properties</h2> |
| 300 | |
| 301 | <p>Most dalvik.vm properties in ART are similar to Dalvik, but there are a few |
| 302 | additional ones as described below. Note that these options affect dex2oat |
| 303 | during on-device compilation as well as during pre-optimization, whereas most |
| 304 | of the options discussed above affect only pre-optimization.</p> |
| 305 | |
| 306 | <p>To control dex2oat while it’s compiling the boot image:</p> |
| 307 | |
| 308 | <ul> |
| 309 | <li>dalvik.vm.image-dex2oat-Xms: initial heap size |
| 310 | <li>dalvik.vm.image-dex2oat-Xmx: maximum heap size |
| 311 | <li>dalvik.vm.image-dex2oat-filter: compiler filter option |
| 312 | </ul> |
| 313 | |
| 314 | <p>To control dex2oat while it’s compiling everything besides the boot image:</p> |
| 315 | |
| 316 | <ul> |
| 317 | <li> dalvik.vm.dex2oat-Xms: initial heap size |
| 318 | <li> dalvik.vm.dex2oat-Xmx: maximum heap size |
| 319 | <li> dalvik.vm.dex2oat-filter: compiler filter option |
| 320 | </ul> |
| 321 | |
| 322 | <p>The options that control initial and maximum heap size for dex2oat should not |
| 323 | be reduced since they could limit what applications can be compiled.</p> |
| 324 | |
| 325 | <h2 id=sample_usage>Sample Usage</h2> |
| 326 | |
| 327 | <p>The goal of these compiler options is to utilize available space in the system |
| 328 | and data partition to reduce the amount of dex2oat that must be performed by |
| 329 | the device. </p> |
| 330 | |
| 331 | <p>For devices with ample system and data space, enabling dex pre-optimization is |
| 332 | all that is necessary. |
| 333 | |
| 334 | <p>BoardConfig.mk:</p> |
| 335 | |
| 336 | <pre><code>WITH_DEXPREOPT := true</code></pre> |
| 337 | |
| 338 | <p>If this causes the system image to become too large, the next thing to try is |
| 339 | disabling pre-optimization of the prebuilts. |
| 340 | |
| 341 | <p>BoardConfig.mk:</p> |
| 342 | |
| 343 | <pre><code>WITH_DEXPREOPT := true |
| 344 | DONT_DEXPREOPT_PREBUILTS := true</code></pre> |
| 345 | |
| 346 | <p>Again, if the system image is still too large, try pre-optimizing only the boot |
| 347 | image. |
| 348 | |
| 349 | <p>BoardConfig.mk:</p> |
| 350 | |
| 351 | <pre><code>WITH_DEXPREOPT := true |
| 352 | WITH_DEXPREOPT_BOOT_IMG_ONLY := true</code></pre> |
| 353 | |
| 354 | <p>However, limiting to pre-optimizing only the boot-image means all apps will |
| 355 | have to be optimized on first boot. In order to avoid this, it is possible to |
| 356 | combine these high level flags with more fine-grained controls to maximize the |
| 357 | amount of pre-optimized apps.</p> |
| 358 | |
| 359 | <p>For instance, if disabling the pre-optimization of the prebuilts almost fits |
| 360 | into the system partition, compiling the boot classpath with the ‘space’ option |
| 361 | may make it fit. Note this compiles fewer methods in the boot classpath, |
| 362 | potentially interpreting more code and impacting runtime performance. |
| 363 | |
| 364 | <p>BoardConfig.mk:</p> |
| 365 | |
| 366 | <pre><code>WITH_DEXPREOPT := true |
| 367 | DONT_DEXPREOPT_PREBUILTS := true</code></pre> |
| 368 | |
| 369 | <p>device.mk:</p> |
| 370 | |
| 371 | <pre><code>PRODUCT_DEX_PREOPT_BOOT_FLAGS := --compiler-filter=space</code></pre> |
| 372 | |
| 373 | <p>If a device has very limited system partition space, it’s possible to compile a |
| 374 | subset of classes in the boot classpath using the compiled classes list. Boot |
| 375 | classpath methods that aren’t in this list will have to be interpreted, which |
| 376 | could affect runtime performance. |
| 377 | |
| 378 | <p>BoardConfig.mk:</p> |
| 379 | |
| 380 | <pre><code>WITH_DEXPREOPT := true |
| 381 | WITH_DEXPREOPT_BOOT_IMG_ONLY := true</code></pre> |
| 382 | |
| 383 | <p>device.mk:</p> |
| 384 | |
| 385 | <pre><code>PRODUCT_COPY_FILES += <filename>:system/etc/compiled-classes</code></pre> |
| 386 | |
| 387 | <p>If a device has both limited space in the system and data partitions, compiler |
| 388 | filter flags can be used to disable compilation of certain apps. This will save |
| 389 | space in both system and data, as there won’t be any compiled code, but these |
| 390 | apps will have to be interpreted. This example configuration would pre-optimize |
| 391 | the boot classpath but prevent compilation of other apps that are not |
| 392 | prebuilts. However, to prevent noticeable performance degradation of |
| 393 | system_server, the services.jar is still compiled but optimized for space. Note |
| 394 | that user-installed applications will still use the default compiler filter of |
| 395 | speed. |
| 396 | |
| 397 | <p>BoardConfig.mk:</p> |
| 398 | |
| 399 | <pre><code>WITH_DEXPREOPT := true |
| 400 | DONT_DEXPREOPT_PREBUILTS := true</code></pre> |
| 401 | |
| 402 | <p>device.mk:</p> |
| 403 | |
| 404 | <pre><code>PRODUCT_DEX_PREOPT_DEFAULT_FLAGS := --compiler-filter=interpret-only |
| 405 | $(call add-product-dex-preopt-module-config,services,--compiler-filter=space)</code></pre> |
| 406 | |
| 407 | <p>For a major version upgrade OTA, it can be useful to blacklist certain apps |
| 408 | from being pre-optimized since they will likely be out of date. This can be |
| 409 | done by specifying <code>LOCAL_DEX_PREOPT</code> (for all products) or with |
| 410 | <code>PRODUCT_DEX_PREOPT_MODULE_CONFIGS</code> (for a particular product). |
| 411 | |
| 412 | <p>BoardConfig.mk:</p> |
| 413 | |
| 414 | <pre><code>WITH_DEXPREOPT := true</code></pre> |
| 415 | |
| 416 | <p>Android.mk (of blacklisted apps):</p> |
| 417 | |
| 418 | <pre><code>LOCAL_DEX_PREOPT := false</code></pre> |