Android Internals 101: ART vs. DVM Deep Dive
Android Internals 101: ART vs. DVM Deep Dive
Take a look at Android architecture, compilers, and virtual machines.
Join the DZone community and get the full member experience.Join For Free
In this post, we’ll take a look at the runtime environment in Android and how it has changed over the years. More specifically, we’ll compare ART vs DVM based on installation time, runtime performance, and other optimizations such as app size.
To understand this, let’s first start with some basics.
What Is a Virtual Machine?
A Virtual Machine is an abstraction over a native machine backed by the resources of the native machine. Its job is to convert language-specific code to a format compatible to run on multiple platforms, independent of the underlying hardware.
For example, the JVM runs Java bytecode and produces the same output on multiple platforms; for example, bytecode produced on a Windows machine will be able to run on a JVM running in UNIX machine.
Note: JVM is not platform-independent. It is written in C/C++ and is platform dependent. You’ll always need something to communicate with the underlying architecture.
A virtual machine should be able to carry out all of the operations of a physical CPU. These include:
- Compilation of source code into VM specific code.
- Data Structure to contain operands and instructions.
- Instruction Pointer.
- A Virtual CPU.
We’ll be looking at two ways of implementing a Virtual Machine:
- Stack-based Architecture.
- Register-based Architecture.
A stack is a LIFO data structure, which means what comes in last is computed first. If you’ve taken a class on computer architecture, you’d be familiar with how arithmetic operations work in Stack-based Architecture.
Let’s take an example. Consider the stack given below:
Now, in order to compute the sum of the first two operands, the chain of command would be:
- Pop 20.
- Pop 7.
- Add 20 + 7.
- Push the result onto the stack.
Here are the actual CPU instructions:
- POP 20.
- POP 7.
Note here that for the addition of two integers, we’ve generated three lines of code.
- Shorter lengths of instructions.
- Fast operation as stack pointer immediately points to the next memory location after pop.
- No explicit memory reference required due to stack pointer.
- Size of the program increases.
A register is a piece of the processor that can hold various types of data, such as operands, instruction, memory location, etc.
The length of an instruction a register can store depends on the architecture of the machine. For example, a 64-bit machine has registers that can hold 64-bit instructions.
Here is the format of an instruction in a MIPS32 Register-based architecture:
Now, if we were to perform the same addition operation as in Stack-based register, it would look something like this:
- ADD R1, R2, R3
What this instruction adds R2 and R3 and stores the result in R1. Notice how we complete the operation with a single instruction. This is the main advantage of Register-based Architecture over Stack-based Architecture.
On average, Register-based Architecture has to run 47% fewer instructions than Stack-based Architecture. However, the register code is 25% larger than Stack-based code.
This knowledge of Stack-based architecture and Register-based architecture will come in handy when we talk about ART vs. DVM in Android, as well as JVM vs. DVM in the next section.
JVM vs. DVM
Java bytecode can be run on any machine capable of running JVM.
Here is the architecture of JVM:
It has a Stack-based Architecture. A stack-based architecture is simple to implement and has few assumptions about the underlying hardware. It can be run on machines with lesser registers. JVM is capable of running only .class files and uses the JIT compiler.
The DVM (Dalvik Virtual Machine) was created by Dan Bornstein and his team with the constraints of mobile devices in mind. It was a purpose-specific virtual machine and was strictly created for mobile devices.
Here is a paper by David Ehringer that explains the Architecture of Dalvik Virtual Machine.
Unlike the JVM, DVM uses a register-based architecture, runs .dex files (and can convert .class files into .dex files). Similarly to JVM, it uses the JIT compiler.
AOT vs. JIT
This section is very crucial in understanding the comparison of ART vs. DVM in Android. The main difference between ART and DVM is that ART uses AOT compilation; whereas, DVM uses JIT compilation.
More recently, ART has started using a hybrid of AOT and JIT. We’ll look into that in a later section.
- JIT (Just In Time) compiler compiles source code into machine code during runtime. This means that each time your app is run, a part of a .dex file is converted dynamically.
- As execution goes on, more of the code is compiled and cached.
- Each file is compiled separately.
- A JIT compiler can optimize old programs, as the JIT compilation process is optimized. This is not true for AOT compilation, as source code is compiled beforehand.
- Adapting to run-time metrics. A JIT-compiler can not only look at the code and the target system, but also at how the code is used. It can instrument the running code, and make decisions about how to optimize according to, for example, what values the method parameters happen to have.
- Compiles the source code before execution.
- Improves runtime performance.
- Increases overhead during application install.
- Cannot perform optimizations such as runtime profile guided optimizations.
- Can perform complex and advanced code optimizations, which, in most cases of JITing, are considered too costly.
With this knowledge, we’re ready to take a look at ART vs. DVM in Android.
ART vs. DVM in Android
DVM was designed specifically for mobile devices and was used as a virtual machine for running Android apps up until Android 4.4 Kitkat.
Programs for Android are written in Java and compiled to bytecode. For DVM, this bytecode was eventually converted to .dex or .odex (Optimized Dalvik EXecutable) files.
Ever since Android 4.4 Kitkat, DVM was replaced by ART (Android Runtime), which uses AOT compilation, unlike DVM, which used JIT.
- ART uses AOT compilation. Has stricter install-time verification than DVM.
- AOT uses dex2oat tool to compile .dex files and generates a compiled app to be run on the target device.
- Garbage collection is one of the main reasons for a poor UX, poor responsiveness, and ultimately bad reviews. In the Dalvik days, GC used to have two passes over the heap, which led to poor UXs.
- This situation is improved in ART, as only one pass over the heap to consolidate the memory is required.
- ART uses parallelized processing during the remaining GC pause.
- ART uses a collector with a lower total GC time for cleaning up recently-allocated, short-lived objects.
- Improved garbage collection ergonomics make concurrent garbage collections more timely, which makes GC_FOR_ALLOC events extremely rare in typical use cases.
- Compacting GC reduces background memory usage and fragmentation, leading to improved performance in app startup, as there is no runtime compilation.
Other improvements in ART and Dalvik in Android can be read here.
- Uses JIT compilation.
- It leads to slow app startup, as the code is JIT'ed each time the app starts.
- Leads to faster boot time of the device, as app’s cache is built at runtime.
- Space taken by apps running on DVM has a lower memory footprint than those running on ART, as ART pre-compiles applications.
- The constant pool has been modified to use only 32-bit indices to simplify the interpreter.
- Standard Java bytecode executes 8-bit stack instructions. Local variables must be copied to or from the operand stack by separate instructions. Dalvik, instead, uses its own 16-bit instruction set that works directly on local variables.
- Dalvik is “deprecated” and is no longer used after android 4.4 Kitkat.
Here is an image denoting the difference in Architectures of ART vs DVM
This is the second article in the Android Internals series (here's the first). Let me know what topic you want me to cover next, and I’ll be more than happy to write an article on that.
Published at DZone with permission of Ayusch Jain . See the original article here.
Opinions expressed by DZone contributors are their own.