From Dalvik to ART runtime
The original Android runtime implementation was Dalvik. Dalvik was a virtual machine, specifically created for Android, due to the necessity to target low-memory devices. It was an integral part of the system until Android KitKat.
As we already said, Android applications are mostly written in Java. When Dalvik was the in-use runtime system, the Java code was compiled into bytecode. This bytecode was then translated to Dalvik bytecode and finally stored into a .dex
(Dalvik Executable). After this procedure, Dalvik was able to run the Android app.
Although Dalvik had been designed for slow devices, with low memory, its performance has never been astonishing, not even when the Just-In-Time compilation was introduced, back with Android 2.2 Froyo. Dalvik JIT was supposed to bring a huge performance boost to Android apps and, from some points of view, it did, but with limitations, such as the infamous maximum methods number, and the pressure from alternative solutions forced Google to look forward to a new runtime:
The Android runtime
When Android 4.4 KitKat was released, users could select a new experimental runtime environment in the Settings menu: ART. Android RunTime or, shortened, ART, is the current default runtime solution that replaced Dalvik from Android 5 Lollipop. The previous diagram shows a comparison between Dalvik and ART architecture.
The idea behind Dalvik's JIT (just-in-time) execution was to profile the applications while they were being executed and dynamically compile the most-used segments of the bytecode into native machine code. Native execution of these most-used segments called traces would then greatly speed-up the execution of the application even though most of the code would still be interpreted.
A new old approach – AOT compilation
Art re-introduces the concept of AOT (ahead-of-time) compilation. It works as most compilers do, that is, it compiles the whole application code into the native machine code, without interpreting bytecode at all. This takes some time, but it is done only once when the user downloads the app, so considering the time and amount of resources needed for JIT profiling and optimization that are needed on every application start, it is an acceptable trade-off. Also, since the whole application is now compiled, it is quicker overall and the power consumption is reduced, which improves the device autonomy.
ART is the default runtime since Android 5, but Android needs to ensure compatibility with all those apps that are already on the market and all those devices that are running a previous version of Android and won't receive any operating system updates.
For backward compatibility reasons, the input bytecode is the same for ART and Dalvik. The application APK file still contains standard .dex
files, but replaces the .odex
files (Optimized Dalvik Executables) with the standard Unix ELF files (Executable and Linkable Format). During the installation, ART uses dex2oat
utility to compile the bytecode into native code stored in the ELF file. As already mentioned, this step is performed only once and requires fewer resources and less overhead than Dalvik's JIT compilation. The downside is that the APK files are larger because they effectively contain double the code (uncompiled bytecode and compiled executable). After this compilation, the system will run just the ELF executable.
The bottom line is faster apps, but a bit less free space on your smartphone memory.
Garbage collection and other improvements
AOT compilation is not the only improvement that ART brought in. One of the most important features is the improved garbage collection. Garbage Collection (GC) is a form of automatic memory management, completely different from the old idea where the developer was the one in charge of allocating memory when needed and freeing it when it was not needed anymore.
The whole philosophy is based on the concept of Garbage Collector, an entity that tries to reclaim memory occupied by objects that are not used anymore in the program. It's a well-known tool in the Java world and Android has always suffered from its downside—GC is very slow and blocking.
Android 2.3 introduced the concurrent garbage collector—GC is not blocking the app anymore when it occurs, but there will always be an overall slowdown when it occurs. Finally, ART introduced a few more performance improvements:
- Just one pause for garbage collection instead of Dalvik's two pauses
- GC processing is now parallelized, reducing the duration of the GC pause
- New Rosalloc memory allocator that uses thread-local region allocations for smaller objects and separate locks for bigger objects, instead of a single global lock
- Full garbage collection is run only when the phone is locked so that the user doesn't notice when the GC is run
- There is a compacting GC that reduces memory fragmentation and so diminishes the need to kill other applications just because bigger contiguous memory chunks are needed
From a development and debugging point of view, ART brought in the support for sampling profiler, support for more debugging features, and improved diagnostic details in exceptions and crash reports.
Waiting for Android Nougat
The upcoming version of Android will bring some enhancement to the current ART runtime. Google will introduce a so-called Profile-guided JIT/AOT compilation. JIT stands for Just In Time and looks similar to the old Dalvik approach: a compiler with code profiling capabilities. This JIT compiler will work together with ART and will provide constant performance improvement as it will continuously be profiling code and resource usage.
To improve performance during the installation phase, ART won't pre-compile Ahead-Of-Time the whole app. Instead, thanks to the profiling approach, it will detect hot methods in the app and will only pre-compile them, leaving unused parts of the app uncompiled. This precompilation process is smartly performed when the device is idle and charging, to have the smallest negative impact on the user experience and allow the user to install in instants apps that in Android 6 would take several seconds to be installed.
This whole new approach aims to improve applications and system performance on low end devices, reducing RAM memory footprint, battery draining and increasing runtime performance, for a satisfying Android experience on a wide range of devices.