ART: what it is, runtime and how it works

Author: IT Sectr Published: 2026-04-16 Reading time: 10 min

Android Runtime (ART) is the Android application runtime environment, introduced in Android 5.0 Lollipop as a replacement for Dalvik. The main innovation is ahead-of-time AOT compilation of DEX bytecode into native machine code directly during application installation, eliminating the long-standing problem of JIT compiler warm-up. According to Google, 2024, ART provides a performance increase of 20–30% compared to Dalvik while maintaining full backward compatibility with the DEX format.

Key Takeaways

  • ART is the Android runtime with AOT compilation, replacing Dalvik in Android 5.0.
  • AOT compilation converts DEX bytecode into native machine code during app installation.
  • Hybrid JIT+AOT mode (since Android 7.0) speeds up installation and maintains high performance.
  • Garbage collection in ART is improved: pauses reduced to 2–3 ms thanks to generational collector.
  • ART maintains backward compatibility with Dalvik DEX bytecode and supports Java 8+ features.

What is ART?

Android Runtime (ART) is an application runtime environment that compiles DEX bytecode into native machine code before execution. Unlike Dalvik, which used Just-In-Time compilation during runtime, ART performs Ahead-Of-Time (AOT) compilation during APK installation. This fundamental architectural change led to significant application acceleration and reduced power consumption.

ART first appeared as an experimental option in Android 4.4 KitKat. Developers could enable it in developer settings and test their applications. In Android 5.0 Lollipop, ART became the default runtime, and Dalvik was completely removed from the platform. By the time Android 7.0 Nougat was released, ART received a hybrid compilation mode.

History of Development

The decision to replace Dalvik with ART was not sudden. Work on the new runtime began in 2012 when Google recognized the limitations of the JIT approach. Main goals: accelerating app launch, reducing CPU load, and decreasing power consumption. Development was led by the Android Runtime Group, previously working on Dalvik optimizations.

Architectural Changes

ART uses the same register-based architecture as Dalvik, but with a completely redesigned compiler. Instead of an interpreter and JIT compiler, ART includes the dex2oat AOT compiler, which converts DEX files into ELF binaries during installation. As a result, applications on ART start with native performance immediately, without a warm-up phase.

ART Architecture: From Dalvik to the New Runtime

ART retained Dalvik’s key principles: application isolation through separate processes, register-based architecture, and DEX format support. However, the internal implementation was completely rewritten. Instead of the Dalvik interpreter, ART includes three execution modes: interpreter, JIT compiler, and dex2oat AOT compiler. The mode selection depends on the application’s lifecycle stage.

The key component of ART is dex2oat (dalvik executable to optimized android translator). This utility runs during application installation (since Android 7.0 — also during background optimization). dex2oat reads DEX files from the APK, optimizes the bytecode, and generates an OAT file — an ELF binary with native code. OAT files are stored in the /data/dalvik-cache/ directory.

bash
# Checking OAT files on device
adb shell ls -la /data/dalvik-cache/arm64/

# Forced recompilation of the application
adb shell cmd package compile -m speed com.example.app

ART Components

The ART system consists of several interconnected modules. The dex2oat compiler handles native code generation. The garbage collector (GC) manages memory deallocation. The interpreter executes infrequently called code without compilation. The profiler tracks hot methods for hybrid compilation. Each module can operate independently, making ART flexible and scalable.

Hybrid Compilation: JIT + AOT + Profiling

Starting with Android 7.0 Nougat, ART uses a hybrid approach to compilation, combining the advantages of JIT and AOT. During application installation, ART no longer performs full AOT compilation — instead, the app runs in interpreted mode with JIT compilation of hot methods. This reduces installation time and storage space.

A background profiler works in parallel. It collects execution statistics: which methods are called most frequently, which code branches are executed, which classes are loaded. After accumulating sufficient data (typically after 2–3 app launches), ART runs dex2oat in the background and compiles only the profiled hot methods into native code.

Compilation Modes

ART supports several compilation modes, managed through system_server. “speed” mode compiles all methods with AOT (maximum performance, long installation). “speed-profile” mode compiles only profiled hot methods (balance of speed and size). “verify” mode only verifies bytecode without compilation (minimum space, interpretation). By default, speed-profile is used — optimal for most applications.

ModeCompilationInstallation TimePerformance
speedFull AOTSlowMaximum
speed-profileProfiled AOTFastHigh
verifyNo compilationInstantInterpretation
spaceMinimal AOTMediumMedium

ART Profiler

The profiler collects execution data into special .prof files. Each application stores its profile in /data/misc/profiles/. When the threshold is reached (usually 1000 samples), the profiler launches dex2oat to compile the identified hot methods. Profiles are preserved between application updates, speeding up re-optimization after OTA system updates.

Garbage Collection in ART

Garbage collection in ART is dramatically improved compared to Dalvik. Instead of the single-threaded Concurrent Mark and Sweep (CMS), ART uses a generational collector with several optimizations: moving collector (heap compaction), large object space (separate storage for large objects), and concurrent compaction (parallel compaction).

A typical GC pause in ART is 2–3 ms compared to 5–10 ms in Dalvik. This became possible through several mechanisms. First, ART uses read-barrier instead of stop-the-world for concurrent phases. Second, the generational collector processes only the young generation of objects in most cycles, without touching the entire heap. Third, the large object space (LOS) is allocated separately and does not participate in regular GC cycles.

java
// Enabling GC logs for debugging
System.logV("ART", "GC trigger: allocation failed");

// Forced GC call (not recommended in production)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    Debug.getRuntimeIStats();
}

Memory Leaks in the ART Era

Despite the improved GC, memory leaks remain a relevant problem. An ART-specific cause is loading native libraries through JNI without proper deallocation. If native code allocates memory through malloc but does not call free, ART cannot free this memory — it is outside the managed heap. The AddressSanitizer tool in Android NDK helps identify such leaks.

ART vs Dalvik: Comparative Analysis

ART and Dalvik are two fundamentally different implementations of the same task: executing Android applications. The differences affect all levels: from compilation to memory management. Below is a comparison of key performance and compatibility parameters.

The main advantage of ART is elimination of JIT warm-up. On Dalvik, an app could lag for the first 3–10 seconds while JIT compiled hot methods. On ART, all methods are already compiled into native code (or will be compiled in the background). This is especially noticeable in games and apps with heavy UI: the fps difference can reach 15–20% in favor of ART.

ParameterDalvikART
CompilationJIT (during runtime)AOT + hybrid (at installation)
Launch Time3–10 s (warm-up)Instant
APK Size~6–7 MB (DEX)+20% (OAT)
GC Pauses5–10 ms2–3 ms
Power ConsumptionHigher (JIT heats CPU)Lower (native code)

Compatibility

All applications written for Dalvik work on ART without changes. Google guarantees full backward compatibility at the DEX bytecode level. The exception is code using Dalvik-specific internal API via reflection: dalvik.system.DexFile class members marked with @hide in the Android SDK. Such code should be updated to use public APIs.

Java 8 Support and Desugaring

ART became the first Android runtime with native Java 8 feature support. Starting with Android 7.0, ART includes desugaring — the process of converting Java 8 constructs (lambdas, method references, Stream API) into equivalent Java 7 code. This allows using modern syntax without losing compatibility with older devices.

Desugaring is performed by the D8 compiler and works as follows. Source code with a lambda is converted into a synthetic method within the same class, and the lambda is replaced with an invoke-custom call. ART’s runtime includes support for the invoke-custom instruction, added specifically for Java 8. On devices with Android 6.0 and below, lambdas are desugared into anonymous classes.

java
// Java 8 lambda — desugaring in ART
button.setOnClickListener(v -> handleClick(v));

// After desugaring (Java 7 equivalent)
button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        handleClick(v);
    }
});

Desugaring Limitations

Not all Java 8 features are supported by desugaring. java.time API (dates and time) is only available through desugar_jdk_libs — an additional library added to build.gradle. Stream API also requires desugar_jdk_libs. java.util.function and Optional work without additional dependencies. Full Java 8 support is available on devices with Android 8.0 and above without desugaring.

App Optimization for ART

Although ART is backward compatible, some optimization practices improve performance specifically on this runtime. The main recommendation is to minimize reflection. ART compiles methods visible at compile time into direct machine code calls. Reflection forces ART to generate additional stubs, slowing execution by 10–15%.

Starting with Android 9.0, ART introduced support for App Startup Optimization. The developer can mark initialization classes in the manifest via <initialization>, and ART will preload them at app startup. This reduces launch time by 5–15% for applications with many plugins or libraries.

xml
<!-- App Startup Optimization in AndroidManifest.xml -->
<application>
    <profileable
        android:shell="true"
        android:enable="true" />
</application>

Performance Testing

To measure performance on ART, use systrace and perfetto. Systrace shows dex2oat compilation time, GC frequency, and frame rendering speed. Perfetto provides more detailed information: thread distribution, JNI transition time, native library loading. Launch: adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto -t 10s sched freq idle am wm.

Frequently Asked Questions

What is ART in Android?

ART (Android Runtime) is the Android application runtime environment that compiles app code into machine code during installation. This speeds up app launch and operation compared to the old Dalvik runtime.

How is ART different from Dalvik?

ART compiles code ahead of time (AOT) during application installation, while Dalvik compiled it piece by piece during runtime (JIT). Therefore, on ART, applications launch faster and consume less power.

How to check if an application is running on ART?

Run adb shell getprop and find the persist.sys.dalvik.vm.lib.2 property. The value “libart.so” means ART, “libdvm.so” means Dalvik. All devices with Android 5.0+ use ART as the runtime.

Does ART affect APK size?

Minimally. The application itself remains in APK format with DEX files. ART creates an additional OAT file in /data/dalvik-cache/, which takes 10–20% more space than the original DEX, but this storage is not included in the APK size.

Does ART support Java 8?

Yes, ART supports most Java 8 features through the desugaring mechanism. Lambdas, method references, and functional interfaces work on all devices with Android 5.0+. Stream API and java.time require the desugar_jdk_libs library.

Summary

  • ART is the Android runtime that replaced Dalvik in Android 5.0 Lollipop with a fundamentally different approach to compilation.
  • AOT compilation dex2oat converts DEX bytecode into native ELF binary during application installation.
  • Hybrid JIT + AOT mode (Android 7.0+) speeds up installation and adapts to actual usage.
  • The generational garbage collector in ART reduced GC pauses from 5–10 ms to 2–3 ms.
  • The profiler collects data over 2–3 launches and triggers background compilation of hot methods.
  • Java 8 desugaring enables lambdas and Stream API on devices with Android 5.0+.
  • For optimal performance on ART, minimize reflection and use App Startup Optimization.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also