Dalvik is a discontinued process virtual machine (VM) in the Android operating system that executes applications written for Android. (Dalvik bytecode format is still used as a distribution format, but no longer at runtime in newer Android versions.) Dalvik was an integral part of the Android software stack in the (now unsupported) Android versions 4.4 "KitKat" and earlier, which were commonly used on mobile devices such as mobile phones and tablet computers, and more in some devices such as smart TVs and wearables. Dalvik is open-source software, originally written by Dan Bornstein, who named it after the fishing village of Dalvík in Eyjafjörður, Iceland.
Programs for Android are commonly written in Java and compiled to bytecode for the Java Virtual Machine, which is then translated to Dalvik bytecode and stored in .dex (Dalvik EXecutable) and .odex (Optimized Dalvik EXecutable) files; related terms odex and de-odex are associated with respective bytecode conversions. The compact Dalvik Executable format is designed for systems that are constrained in terms of memory and processor speed.
The successor of Dalvik is Android Runtime (ART), which uses the same bytecode and .dex files (but not .odex files), with the succession aiming at performance improvements. The new runtime environment was included for the first time in Android 4.4 "KitKat" as a technology preview, and replaced Dalvik entirely in later versions; Android 5.0 "Lollipop" is the first version in which ART is the only included runtime.
Architecture
Unlike Java Virtual Machines, which are stack machines, the Dalvik VM uses a register-based architecture that requires fewer, typically more complex, virtual machine instructions. Dalvik programs are written in Java using the Android application programming interface (API), compiled to Java bytecode, and converted to Dalvik instructions as necessary.
A tool called dx is used to convert Java .class files into the .dex format. Multiple classes are included in a single .dex file. Duplicate strings and other constants used in multiple class files are included only once in the .dex output to conserve space. Java bytecode is also converted into an alternative instruction set used by the Dalvik VM. An uncompressed .dex file is typically a few percent smaller in size than a compressed Java archive (JAR) derived from the same .class files.
The Dalvik executables may be modified again when installed onto a mobile device. In order to gain further optimizations, byte order may be swapped in certain data, simple data structures and function libraries may be linked inline, and empty class objects may be short-circuited, for example.
Being optimized for low memory requirements, Dalvik has some specific characteristics that differentiate it from other standard VMs:
The VM was slimmed down to use less space. 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. The local variable is commonly picked by a 4-bit "virtual register" field. This lowers Dalvik's instruction count and raises its interpreter speed.
According to Google, the design of Dalvik permits a device to run multiple instances of the VM efficiently.
Android 2.2 "Froyo" brought trace-based just-in-time (JIT) compilation into Dalvik, optimizing the execution of applications by continually profiling applications each time they run and dynamically compiling frequently executed short segments of their bytecode into native machine code. While Dalvik interprets the rest of application's bytecode, native execution of those short bytecode segments, called "traces", provides significant performance improvements.
Performance
The relative merits of stack machines versus register-based approaches are a subject of ongoing debate.
Generally, stack-based machines must use instructions to load data on the stack and manipulate that data, and, thus, require more instructions than register machines to implement the same high-level code, but the instructions in a register machine must encode the source and destination registers and, therefore, tend to be larger. This difference is of importance to VM interpreters, for which opcode dispatch tends to be expensive, along with other factors similarly relevant to just-in-time compilation.