ART is the Android Runtime system that replaced the older Dalvik virtual machine starting with Android 5.0. 1 It's responsible for executing Android applications by compiling DEX (Dalvik Executable) bytecode into native machine code.
ART consists of several key services and components:
Runtime Libraries: The main runtime is implemented in libart.so
(release) and libartd.so
(debug), which provide the core execution environment. 2 3
artd Service: A privileged daemon that handles DEX optimization, profile management, and artifact cleanup operations. 4 This service implements the AIDL interface for system-level operations like dexopt
, mergeProfiles
, and deleteArtifacts
. 5
ART Service: Manages dexopt artifacts of apps, allowing you to dexopt apps, query their dexopt status, and delete dexopt artifacts. 6
DEX Optimization: ART compiles DEX bytecode ahead-of-time (AOT) using dex2oat
, creating optimized .oat
, .vdex
, and .art
files. 7 The system supports different compiler filters like "verify", "speed", and "speed-profile" depending on the optimization scenario. 8
Runtime Execution: The art
script provides a wrapper for executing applications on the ART runtime, supporting both 32-bit and 64-bit execution modes. 9 It can run with different runtime libraries and debugging options. 10
Testing Infrastructure: ART includes comprehensive testing with over 400 run-tests that exercise the runtime using DEX bytecode, plus C++ gtests for various runtime aspects. 11
ART optimizes applications in several scenarios:
- First boot after OTA updates (using "verify" filter)
- App installation (using "speed-profile" with cloud profiles or "verify" without)
- Idle device charging (background optimization)
- Mainline updates (optimizing system UI and launcher) 12
The codebase shows ART as a comprehensive runtime system that has evolved significantly from the original Dalvik VM, with sophisticated ahead-of-time compilation, profile-guided optimization, and extensive tooling for development and testing.
Wiki pages you might want to explore:
File: libartservice/service/README.md (L1-14)
## ART Service
Warning: The contents in this doc can become stale while the code evolves.
ART Service manages dexopt artifacts of apps. With ART Service, you can dexopt
apps, query their dexopt status (the compiler filter, the compilation reason,
whether the dexopt artifacts are up-to-date, etc.), and delete dexopt artifacts.
Note: ART Service is introduced since Android U. Prior to ART Service, dexopt
artifacts were managed by Package Manager with a legacy implementation. ART
Service is the default on Android U, while partners are allowed to opt-out and
use the legacy implementation instead. The legacy implementation will be removed
since Android V. This doc only describes ART Service, not the legacy
implementation.
File: libartservice/service/README.md (L31-34)
### Compiler filters
See
[Compilation options](https://source.android.com/docs/core/runtime/configure#compilation_options).
File: libartservice/service/README.md (L38-90)
At a high level, ART Service dexopts apps in the following senarios:
- the device is on the very first boot
- the device is on the first boot after an OTA update
- the device is on the first boot after a mainline update
- an app is being installed
- the device is idle and charging
Tip: The compilation reason, stored in the header of the OAT file, shows the
senario, in which the app is dexopted.
The sections below describe the default behavior in each senario. Note that the
list of apps to dexopt and the compiler filter, as well as other options, can be
customized by partners through a callback.
#### On the very first boot / the first boot after an OTA update
On the very first boot / the first boot after an OTA update, ART Service only
dexopts primary dex files of all apps with the "verify" compiler filter.
Note: It doesn't dexopt secondary dex files or use the "speed-profile" filter
because doing so may block the boot for too long.
Note: In practice, ART Service does nothing for most of the apps because the
apps on the system partitions have dexopt artifacts generated by dexpreopt, and
the apps on the data partition still have VDEX files usable even though their
dependencies (bootclasspath and class loader context) have probably changed. In
this senario, ART Service mostly dexopt apps in APEXes because they are not
supported by dexpreopt.
#### On the first boot after a mainline update
On the first boot after a mainline update, ART Service dexopts the primary dex
files of the system UI and the launcher. It uses the "speed" compiler filter for
the system UI, and uses the "speed-profile" compiler filter for the launcher.
Note: It only dexopts those two apps because they are important to user
experience.
Note: ART Service cannot use the "speed-profile" compiler filter for the system
UI because the system UI is dexpreopted using the "speed" compiler filter and
therefore it's never JITed and as a result there is no profile collected on the
device to use. This may change in the future.
#### During app installation
During app installation, ART Service dexopts the primary dex files of the app.
If the app is installed along with a DM file that contains a profile (known as a
*cloud profile*), it uses the "speed-profile" compiler filter. Otherwise, it
uses the "verify" compiler filter.
Note: If the APK is uncompressed and aligned, and it is installed along with a
DM file that only contains a VDEX file (but not a profile), no dexopt will be
File: runtime/Android.bp (L671-685)
art_cc_library {
name: "libart",
defaults: ["libart_common_defaults"],
apex_available: [
"com.android.art",
"com.android.art.debug",
// libart doesn't go into test_broken_com.android.art, but the libart-broken
// needs to have the same apex_available list as its dependencies in order
// to compile against their sources. Then that change comes back up to affect
// libart as well, because it also needs to have the same apex_available as its
// dependencies.
"test_broken_com.android.art",
],
afdo: true,
}
File: runtime/Android.bp (L705-720)
art_cc_library {
name: "libartd",
defaults: [
"art_debug_defaults",
"libart_defaults",
],
whole_static_libs: [
],
static_libs: [
"libelffiled",
],
shared_libs: [
"libartbased",
"libdexfiled",
"libprofiled",
],
File: artd/artd.h (L70-80)
class Artd : public aidl::com::android::server::art::BnArtd {
public:
explicit Artd(std::unique_ptr<art::tools::SystemProperties> props =
std::make_unique<art::tools::SystemProperties>(),
std::unique_ptr<ExecUtils> exec_utils = std::make_unique<ExecUtils>(),
std::function<int(pid_t, int)> kill_func = kill,
std::function<int(int, struct stat*)> fstat_func = fstat)
: props_(std::move(props)),
exec_utils_(std::move(exec_utils)),
kill_(std::move(kill_func)),
fstat_(std::move(fstat_func)) {}
File: artd/binder/com/android/server/art/IArtd.aidl (L20-29)
interface IArtd {
// Test to see if the artd service is available.
boolean isAlive();
/**
* Deletes artifacts and returns the released space, in bytes.
*
* Throws fatal errors. Logs and ignores non-fatal errors.
*/
long deleteArtifacts(in com.android.server.art.ArtifactsPath artifactsPath);
File: Android.mk (L691-709)
use-art:
$(ADB) root
$(ADB) wait-for-device shell stop
$(ADB) shell setprop persist.sys.dalvik.vm.lib.2 libart.so
$(ADB) shell start
.PHONY: use-artd
use-artd:
$(ADB) root
$(ADB) wait-for-device shell stop
$(ADB) shell setprop persist.sys.dalvik.vm.lib.2 libartd.so
$(ADB) shell start
.PHONY: use-dalvik
use-dalvik:
$(ADB) root
$(ADB) wait-for-device shell stop
$(ADB) shell setprop persist.sys.dalvik.vm.lib.2 libdvm.so
$(ADB) shell start
File: tools/art (L37-71)
function usage() {
cat 1>&2 <<EOF
Usage: art [OPTIONS] [--] [ART_OPTIONS] CLASS
Supported OPTIONS include:
--32 Use the 32-bit Android Runtime.
--64 Use the 64-bit Android Runtime.
-d Use the debug ART library (libartd.so).
--debug Equivalent to -d.
--gdb Launch the Android Runtime in gdb.
--gdbserver <comms> Launch the Android Runtime in gdbserver using the
supplied communication channel.
--help Display usage message.
--invoke-with <program> Launch the Android Runtime in <program>.
--perf Launch the Android Runtime with perf recording.
--perf-report Launch the Android Runtime with perf recording with
report upon completion.
--profile Run with profiling, then run using profile data.
--verbose Run script verbosely.
--no-clean Don't cleanup oat directories.
--no-compile Don't invoke dex2oat before running.
--allow-default-jdwp Don't automatically put in -XjdwpProvider:none.
You probably do not want this.
The ART_OPTIONS are passed directly to the Android Runtime.
Example:
art --32 -cp my_classes.dex MainClass
Common errors:
1) Not having core.art available (see $ANDROID_BUILD_TOP/art/Android.mk).
eg m -j32 build-art-host
2) Not having boot.art available (see $ANDROID_BUILD_TOP/build/make/core/dex_preopt_libart_boot.mk)
eg m -j32 out/target/product/generic_x86_64/dex_bootjars/system/framework/x86_64/boot.art
EOF
File: tools/art (L349-364)
--32)
ART_BINARY=dalvikvm32
DEX2OAT_SUFFIX=32
;;
--64)
ART_BINARY=dalvikvm64
DEX2OAT_SUFFIX=64
;;
-d)
;& # Fallthrough
--debug)
LIBART="libartd.so"
DEX2OAT_BINARY="dex2oatd"
# Expect that debug mode wants all checks.
EXTRA_OPTIONS+=(-XX:SlowDebug=true)
;;
File: test/README.md (L1-6)
# ART Testing
There are two suites of tests in the Android Runtime (ART):
* _ART run-tests_: Tests of the ART runtime using Dex bytecode (mostly written
in Java).
* _ART gtests_: C++ tests exercising various aspects of ART.