This page discusses how to configure ART and its compilation options. Topics addressed here include configuration of pre-compilation of the system image, dex2oat compilation options, and how to trade off system partition space, data partition space, and performance.

See ART and Dalvik, the Dalvik Executable format, and the remaining pages on source.android.com to work with ART. See Verifying App Behavior on the Android Runtime (ART) to ensure your apps work properly.

How ART works

ART uses ahead-of-time (AOT) compilation, and starting in Android 7.0 (Nougat or N), it uses a hybrid combination of AOT, just-in-time (JIT) compilation, and profile-guided compilation. The combination of all these compilation modes is configurable and will be discussed in this section. As an example, Pixel devices are configured with the following compilation flow:

  1. An application is initially installed without any AOT compilation. The first few times the application runs, it will be interpreted, and methods frequently executed will be JIT compiled.
  2. When the device is idle and charging, a compilation daemon runs to AOT-compile frequently used code based on a profile generated during the first runs.
  3. The next restart of an application will use the profile-guided code and avoid doing JIT compilation at runtime for methods already compiled. Methods that get JIT-compiled during the new runs will be added to the profile, which will then be picked up by the compilation daemon.

ART comprises a compiler (the dex2oat tool) and a runtime (libart.so) that is loaded for starting the Zygote. The dex2oat tool takes an APK file and generates one or more compilation artifact files that the runtime loads. The number of files, their extensions, and names are subject to change across releases, but as of the Android O release, the files being generated are:

Compilation options

Compilation options for ART are of two categories:

  1. System ROM configuration: what code gets AOT-compiled when building a system image.
  2. Runtime configuration: how ART compiles and runs applications on a device.

One core ART option to configure these two categories is compiler filters. Compiler filters drive how ART compiles DEX code and is an option passed to the dex2oat tool. Starting in Android O, there are four officially supported filters:

System ROM configuration

There are a number of ART build options available for configuring a system ROM. How to configure these options depends on the available storage space for /system and the number of pre-installed applications. The JARs/APKs that are compiled into a system ROM can be divided in four categories:

Makefile options

Boot classpath configuration

Runtime configuration

Jit options

The following options affect Android releases only where the ART JIT compiler is available.

Package manager options

Since Android 7.0, there's a generic way to specify the level of compilation/verification that happened at various stages. The compilation levels can be configured via system properties with the defaults being:

Dex2oat options

Note that these options affect dex2oat during on-device compilation as well as during pre-optimization, whereas most of the options discussed above affect only pre-optimization.

To control dex2oat while it’s compiling the boot image:

To control dex2oat while it’s compiling everything besides the boot image:

On releases through Android 6.0, one additional option is provided for compiling everything besides the boot image:

Starting with Android 6.1, this becomes two additional options for compiling everything besides the boot image:

Starting with Android 7.1, two options are provided for controlling how memory is used when compiling everything besides the boot image:

The options that control initial and maximum heap size for dex2oat should not be reduced since they could limit what applications can be compiled.

A/B specific configuration

ROM configuration

Starting in Android 7.0, devices may use two system partitions to enable A/B system updates. To save on the system partition size, the preopted files can be installed in the unused second system partition. They are then copied to the data partition on first boot.

Example usage (in device-common.mk):

PRODUCT_PACKAGES += \
     cppreopts.sh
PRODUCT_PROPERTY_OVERRIDES += \
     ro.cp_system_other_odex=1

And in device's BoardConfig.mk:

BOARD_USES_SYSTEM_OTHER_ODEX := true

Note that boot classpath code, system server code, and product-specific core applications always compile to the system partition. By default, all other applications get compiled to the unused second system partition. This can be controlled with the SYSTEM_OTHER_ODEX_FILTER, which has a value by default of:

SYSTEM_OTHER_ODEX_FILTER ?= app/% priv-app/%

Background dexopt OTA

With A/B enabled devices, applications can be compiled in the background for updating to the new system image. See App compilation in background to optionally include the compilation script and binaries in the system image. The compilation filter used for this compilation is controlled with:

pm.dexopt.ab-ota=speed-profile

We recommend using speed-profile to take advantage of profile guided compilation and save on storage.