I. Brief introduction of development
1.1 early – Dalvik
In the early stage of Android system, unlike Java platform, which used JVM to load bytecode files (.class), Dalvik acted as the virtual machine in Android system, and every time the program was run, Dalvik is responsible for loading the dex/ Odex file and parsing it into machine code for the system call. The Dalvik VIRTUAL Machine is an Apache-based Java virtual machine that has been modified to accommodate low-memory, low-processor speed mobile device environments.
1.2 introduced JIT
In order to adapt to the improvement of hardware speed, the Android system is constantly updated, and the single Dalvik VIRTUAL machine has gradually met the requirements of the system. On May 20, 2010, Google released Android 2.2 (Froyo yogurt). In this version, Google added a JUST-in-time Compiler to the Android virtual.
Dalvik uses JIT for just-in-time compilation. With Java HotSpot VM, the JIT compiler can compile and optimize frequently executed dex/ Odex code. Dalvik Code (Smali instruction set) in DEX/Odex was translated into fairly simplified Native Code for execution, and the introduction of JIT improved the performance of Dalvik by 3~6 times.
1.3 the birth of ART
On October 31, 2013, Google released Android 4.4 (Kitkat), bringing a preview of the new VIRTUAL machine RunTime environment ART (Android RunTime) and a new compilation strategy AHEAD-of-time (AOT). At this time, ART and Dalvik coexist, and users can choose between the two.
On October 16, 2014, Google released Android 5.0 (Lollipop), and ART completely replaced Dalvik as the running environment of Android VIRTUAL machine. At this point, Dalvik withdrew from the historical stage. AOT has also become the only compilation mode.
AOT differs from JIT in that JIT compiles at run time, dynamically compiles, and recompiles Odex each time a program is run. AOT, on the other hand, is statically compiled. When the application is installed, dex2OAT process will be started to precompile dex into ELF files. There is no need to recompile every time the program is run, which is a real local application.
1.4 JIT regression
On Android 5.x and 6.x machines, there will be a process of application optimization when the system restarts after OTA upgrade, which is the dex2OAT process mentioned just now, which is time-consuming and takes up extra storage space.
On August 22, 2016, Google released Android 7.0 (Nougat), and the JIT compiler is back, which forms AOT/JIT hybrid compilation mode. This hybrid compilation mode features:
Dex is not compiled when the application is installed
At runtime, the app’s dex file passes through the Interpreter and is executed directly (as it did before Android 2.2 to Android 4.4). At the same time, Hot codes are identified and JIT compiled and stored in the JIT Code cache and a profile is generated to record the Hot Code information. When the phone enters the IDLE or Charging state, the system scans the profile file in the App directory and executes the AOT process to compile it.
As can be seen, the hybrid compilation mode integrates various advantages of AOT and JIT, making the application speed up while optimizing the running speed, storage space, power consumption and other indicators.
Differences between Dalvik and traditional JVMS
Strictly speaking, Dalvik is not a Java VIRTUAL machine, and it does not follow the IMPLEMENTATION specifications of the JVM. Dalvik differs from the JVM in the following ways:
- architecture
The Java virtual machine is stack-based, and the stack-based machine must use instructions to load and manipulate data on the stack. The Dalvik VIRTUAL machine is register-based.
- The bytecode
The Java virtual machine runs Java bytecode. Java classes are compiled into one or more bytecode. Class files, packaged into a. Jar file, and the Java virtual machine gets the bytecode from the corresponding. Dalvik runs its own.dex bytecode format. (Once a Java class is compiled into a.class file, a dx tool converts all.class files into a.dex file from which the Dalvik virtual machine reads instructions and data.)
- Process model
While the JVM is designed to run multiple Instances of Java programs on a single JVM, DVM allows each application to run in its own separate DVM, with each DVM running in a separate process space, preventing the crash of one application from affecting other application processes.
- A mechanism of sharing
DVM has a preload-and-share mechanism that enables different applications to share the same classes at run time, which is more efficient. This sharing mechanism does not exist in the JVM, and different programs are packaged independently.
- The early days of DVM did not use JIT compilation
The JVM uses a JIT compiler, which was not used in the early days of DVM. The early DVM had to compile the DEX code into machine code through the interpreter each time the code was executed, and then hand it over to the system, which was not very efficient. Starting with Android version 2.2, DVM uses a JIT compiler that compiles Code that has been run multiple times (hot Code) to produce fairly compact Native Code so that the next time the same logic is executed, the compiled Native machine Code is used instead of being compiled every time. But this compilation is redone each time the application is rerun, so JIT compilation is required each time the application is re-opened.
The difference between DVM and ART
ART is a runtime environment on the Android operating system that converts the application’s bytecode to machine code when first installed. AOT (Ahead-of-time) technology is used. There are four main differences between DVM and ART:
- JIT and AOT
Every time an application in DVM runs, the bytecode needs to be compiled into machine code by the JIT compiler, which makes the application run less efficiently. In ART, the system will perform an AOT(Ahead of time compilation) when installing applications. Bytecode is pre-compiled into machine code and stored locally. In this way, the application does not need to be compiled each time it runs, which greatly improves the running efficiency and reduces the power consumption of the device.
The first is that AOT takes longer to install, especially for complex applications. The second is that bytecode is precompiled into machine code, which requires more storage space. To address the above shortcomings, ART in Android version 7.0 added the just-in-time compiler JIT as a complement to AOT, which does not compile all the bytecode to machine code at application installation, but instead compiles hot code to machine code at run, shortening application installation time and saving storage space.
- Dealing with figures
DVM was designed for 32-bit cpus, and ART supports 64-bit and is compatible with 32-bit cpus, which is one of the main reasons for DVM’s obsolescence.
- The garbage collection
ART makes improvements to the garbage collection mechanism, such as performing parallel garbage collections more frequently, reducing GC pauses from two to one, and so on.
- Memory division
ART has a different run-time heap partition than DVM.
The advantages and disadvantages of ART can be summarized as follows:
Fourth, garbage recycling
4.1 Dalvik garbage collection
The Dalvik virtual machine is simpler than garbage collection in other Java virtual machines because there is no compacting in memory. This means that the addresses of objects in heap memory never change after they are created, making the rest of the virtual machine relatively easy to implement.
4.1.1 DVM runtime heap
The DVM runtime heap in Android 4.x uses a mark-sweep algorithm for GC. The runtime heap for DVM consists of two Spaces and some auxiliary data structures:
4.1.2 Causes of GC in DVM
There are the following:
-
GC_CONCURRENT: Concurrent GC can free memory when the heap starts filling.
-
GC_POR_MALLOC: GC caused by App trying to allocate memory when the heap is full. The system must stop App and reclaim memory.
-
GC_HPROF_DUMP_HEAP: GC that occurs when a HPROF file is requested to be created to analyze heap memory.
-
GC_EXPLICIT: Explicit GC, such as calling system.gc ()(explicit GC should be avoided and trusted to run when needed).
-
GC_EXTERNAL_ALLOC: applies only to GC whose API level is less than or equal to 10 and is used for externally allocated memory.
4.2 ART garbage collection
Unlike DVM’s GC, ART uses a variety of garbage collection schemes, each of which runs a different garbage collector. By default, ART uses a Concurrent mark-sweep (CMS) scheme, which mainly uses sticky-CMS and partial-CMS. Depending on the CMS scheme, the ART runtime heap space can be divided differently.
4.2.1 ART Runtime heap
The default ART runtime heap consists of four Spaces and multiple helper structures:
When the mark-clear algorithm is used. The space division of DVM and ART is as follows:
4.2.2 Causes of GC in ART
There are the following:
- Concurrent: a Concurrent GC that does not suspend the App thread, runs in a background thread and does not block memory allocation.
- Alloc: GC caused by App’s attempt to allocate memory when the heap is full. This GC occurs in the thread that is allocating memory.
- Explicit: Request garbage collection displayed by App, such as a call to system.gc (). As with DVM, the best practice is to trust GC and avoid explicitly requesting GC, which prevents allocation threads from unnecessarily wasting CPU cycles. If explicitly requesting GC causes other threads to be preempted, it is possible to cause Jank (App draws the same frame multiple times).
- NativeAlloc: Allocating Native memory, such as assigning objects to Bitmaps or RenderScript, causes Native memory stress and triggers GC.
- CollectorTransition: Collection caused by heap transformation, which is caused by a runtime GC switch. Collector transformations involve copying all objects from the free list space to the collision pointer space (and vice versa). Currently, collector transitions occur only when App changes the process state from a perceptible paused state to a perceptible non-paused state (and vice versa) on a device with small memory.
- HomogeneousSpaceCompact: HomogeneousSpaceCompact is the free list to compressed free list space, usually occurs when the App has moved to a perceptible paused process state. The main reason for this is to reduce memory usage and defragment heap memory.
- DisableMovingGc: not really trigger GC, concurrent pile compression occurs, due to the use of the GetPrimitiveArrayCritical, collection will be blocked. In general, it is suggested that don’t use GetPrimitiveArrayCritical, because it has a limit in terms of moving collector.
- HcapTrim: Not the cause of the GC trigger, but note that the collection is blocked until the heap is decluttered.
Five, the summary
This paper briefly describes the development of virtual machine in Android. In fact, at present, the name of ART is very appropriate. DVM begins to have the characteristics of non-virtual machine, while ART cannot be described only by virtual machine.