AOSP Foundations
3 min read

Dalvik vs ART

A technical comparison of Android's runtime environments, explaining the shift from Dalvik JIT to ART's hybrid AOT/JIT compilation.

Android applications are primarily written in Java or Kotlin. The source code is compiled into DEX (Dalvik Executable) bytecode, which must be executed by a runtime environment on the device. Over its history, Android has transitioned between two primary runtimes: Dalvik and the Android Runtime (ART).

Dalvik (Android 1.0 - 4.4)

Dalvik was Android's original virtual machine, designed specifically for early mobile devices with highly constrained memory and CPU resources.

How Dalvik Worked

  • Register-based VM: Unlike standard Java VMs which are stack-based, Dalvik used a register-based architecture to reduce the number of instructions executed.
  • JIT Compilation (Added in 2.2): Dalvik primarily interpreted DEX bytecode. In Android 2.2 (Froyo), a Just-In-Time (JIT) compiler was introduced. The JIT compiler profiled the app at runtime, identified "hot" (frequently executed) methods, and compiled them into native machine code on the fly.

Limitations of Dalvik

  • Runtime Overhead: Interpreting bytecode and running the JIT compiler consumed CPU cycles at runtime, leading to battery drain and occasional UI stuttering.
  • Garbage Collection (GC): Dalvik's GC pauses were often noticeable, causing dropped frames during UI rendering.

Android Runtime (ART) (Android 5.0+)

ART replaced Dalvik entirely in Android 5.0 (Lollipop), prioritizing execution speed and battery life over storage space.

The Initial ART (Android 5.0 - 6.0)

  • Ahead-Of-Time (AOT) Compilation: During application installation, the dex2oat tool compiled the entire DEX bytecode into native ELF executables.
  • Benefits: Because the code was already compiled to native machine code, applications launched faster, ran smoother, and consumed less CPU at runtime. Garbage collection was also significantly optimized.
  • Trade-offs: AOT compilation increased application install times significantly and required more storage space, as the compiled native code footprint was larger than the raw DEX bytecode.

The Modern Hybrid ART (Android 7.0+)

To solve the slow installation times and high storage overhead of pure AOT compilation, Google introduced a hybrid runtime in Android 7.0 (Nougat).

Profile-Guided Compilation

Modern ART uses a sophisticated combination of JIT, AOT, and Profile-Guided Optimization (PGO):

  1. Fast Install: When an app is installed, it is not AOT compiled immediately. This makes installations extremely fast.
  2. JIT Execution & Profiling: When the app runs initially, ART uses JIT compilation. During this time, ART generates a "profile" of the app, recording which methods are executed most frequently.
  3. Background AOT Compilation: When the device is idle and charging, the dex2oat daemon wakes up. It uses the generated profile to perform AOT compilation only on the "hot" methods.
  4. Optimized Execution: The next time the app runs, ART executes the AOT-compiled native code for hot paths, ensuring peak performance.

Cloud Profiles (Android 9.0+)

In Android 9.0 (Pie), Google introduced Cloud Profiles. Google Play aggregates the execution profiles of an app across millions of devices. When a new user downloads the app, they receive this aggregated profile alongside the APK. ART can immediately AOT-compile the most important parts of the app during installation, bypassing the initial JIT phase and delivering peak performance on the very first launch.

Summary

  • Dalvik: Used JIT compilation. Fast installs, smaller storage footprint, but higher runtime CPU overhead and occasional stutters.
  • Initial ART: Used 100% AOT compilation. Smooth runtime performance, but slow installations and larger storage footprint.
  • Modern ART: A hybrid engine utilizing Profile-Guided Optimization and Cloud Profiles. It balances fast installation times with peak runtime performance by identifying and compiling only the code paths that matter most.