1 What is a Dalvik virtual machine
Dalvik is Google's own Java Virtual machine designed for Android, an important part of the Android platform that supports the operation of the DEX format (Dalvik executable) Java application. The DEX format is a compression format designed specifically for Dalvik and is suitable for systems with limited memory and processor speed. Google has specifically optimized it, making Dalvik a highly efficient, concise, and resource-saving feature. From the Android system architecture diagram, the Dalvik virtual machine runs on the Android Runtime Library layer.
2 Dalvik virtual machine capabilities
As a virtual machine designed for Linux and embedded operating systems, Dalvik is primarily responsible for the completion of object lifecycle management, stack management, thread management, security and exception management, and garbage collection. Dalvik takes full advantage of the Linux process management specific, object-oriented design, allowing multiple processes to run concurrently, while traditional Java programs typically run only one process, which is why Android does not use the JVM. Dalvik for optimization purposes, the underlying operations are mostly related to the kernel of the system, or the kernel interface is called directly. In addition, Dalvik did not have a JIT compiler in the early days until Android2.2 added technical support for JIT.
3 Dalvik The difference between a virtual machine and a Java virtual machine
Essentially, Dalvik is also a Java virtual machine. But what is special about it is that the JVM specification is not used. Most Java virtual machines are stack-based (see: Understanding Java Virtual Machine Architecture), while Dalvik virtual machines are based on registers. Stack-based instructions are compact, for example, the instructions used by a Java Virtual machine account for only one byte and are called bytecode. Register-based directives require more space for instruction because they need to specify the source and destination addresses. Some instructions for Dalvik virtual machines take up to two bytes. Stack-based and register-based instruction sets have pros and cons, and in general, performing the same function requires more instruction (mainly load and store instructions), while the latter requires more instruction space. Requiring more instructions means more CPU time, and requiring more instruction space means that data buffering (D-cache) is more likely to fail.
The Java virtual machine is running Java bytecode, and the Dalvik virtual machine is running the proprietary file format dex. In a Java program, the Java class is compiled into one or more class files, packaged into a jar file, and then the Java Virtual Opportunity obtains the corresponding bytecode from the corresponding class file and Jar file. Android apps also use the Java language, but once compiled into a class file, all class files are converted to a Dex file by the Dex tool, which dalvik the virtual machine to read instructions and data from it. The Dex file also improves the class lookup speed in addition to reducing overall file size and I/O operation times.
As you can see, the composition of the Jar and apk files, as well as the difference between the class file and the Dex file. The DEX format file uses a shared, specific type of constant pooling mechanism to conserve memory. A constant pool stores all literal constants in a class, including string constants, field constants, and so on.
In general, Dalvik virtual machines have the following characteristics:
- Byte code in DEX format, incompatible with Java bytecode format
- Low code density, high operational efficiency and resource savings
- A constant pool uses only 32-bit indexes
- There is a memory limit
- Default stack size is 12KB (3 pages, 4KB per page)
- Heap Default boot size is 2MB, default maximum is 16MB
- Heap supports a minimum boot size of 1MB and a maximum supported value of 1024MB
- Heap and stack parameters can be modified by-XMS and-XMX
4 Dalvik System Structure
In fact, Dalvik is based on a partial implementation of the Apache Harmony (Apache Software Foundation's Java SE Project), which provides its own set of libraries, the APIs used by the upper Java application authoring.
To show from Tech-insider. Apache Harmony is broadly divided into three tiers: operating system, Java Virtual machine, Java class Library. It is characterized in that the virtual machine and the class library are highly modular, each module has a certain interface definition. The interface between the operating system layer and the virtual machine layer is defined by the portability layer, which encapsulates the differences between different operating systems and provides a unified set of API access to the underlying system calls for virtual machines and class library native code. The interface between the virtual machine and the class library in addition to the Java specification definition of JNI, Jvmiti, also added a layer of virtual machine interface, composed of kernel class and local code. Virtual machines that implement virtual machine interfaces can be implemented using the Harmony Class library and can be started by the same Java launcher that harmony provides.
The following is a diagram of the Dalvik virtual machine:
An application first passes the DX tool to convert the class file into a Dex file that the Dalvik virtual machine can execute, and then the class loader loads the native class and Java classes, followed by the interpreter to interpret and execute the Dalvik bytecode based on the instruction set. Finally, according to the Dvm_arch parameter, select the compiled target machine architecture.
4.1 Dex File Structure
The Dex file structure differs from the class file structure in many places, but from the information that is carried, the Dex and class files are consistent.
- Header: Stores information such as the start address, offset, and so on for each data type.
- Proto_ids: Describes the function prototype information, including the return value, parameter information. For example, "Test: () V"
- Methods_ids: function information, including the owning class and corresponding proto information.
For more information on the DEX format, the Android security –dex file format is described in detail in this article. Although the structure of the Dex file is compact, it is also necessary to further refine the Dex file if you want to improve performance at runtime. Optimization focuses on the following areas:
- Adjust the byte order of all fields and align each field in the structure
- Verifying all classes in the Dex file
- Optimize the operation code in the method by optimizing some specific classes
When Dex files are optimized, the file size expands to about the original 1~4 times. For built-in apps, the optimization file (odex:optimized dex) is typically generated after the system compiles. An Android application that requires the following procedure to run on a Dalvik virtual machine:
- Compiling the Java source file into a class file
- Convert class files to Dex files using the DX tool
- Use the AAPT tool to combine Dex files, resource files, and Androidmanifest.xml files (binary format) into APK
- Install apk to Android device to run
(from the Web) shows in detail how the APK came from after the final signature.
4.2 Dalvik Class Loader
A DEX file requires the ClassLoader to load the native class and Java classes, and then interprets and executes the Dalvik bytecode based on the instruction set by the interpreter. The Dalvik class loader uses the MMAP function to map the Dex file into memory, access the Dex file through a normal memory read operation, and then parse the contents of the Dex file and load the classes into the hash table.
4.2.1 Parsing dex
In general, the Dex file can be abstracted into three parts: Head, Index, data. The head allows you to know the position and number of the index and the starting position of the data area. After the Dex file is mapped to memory, Dalvik calls the Dexfileparse function to parse it, and the results of the analysis are placed in the Dexfile data structure. The baseaddr in Dexfile points to the starting position of the map area, Pclassdefs points to the starting position of the class index. To speed up the search for class, a hash table is created, the class name is hashed, and the index is generated.
4.2.2 Loading class
After the parsing work is done, the class is loaded, and the loaded classes need to be stored using the CLASSOBJECT data structure.
struct Object { classobject* clazz; // type Object lock; // Lock Objects} object;
Where Clazz points to the Classobject object and also contains a lock object. If the other thread wants to get its lock, only wait for the thread to release. Dalvik a Classobject object for each class loaded, the loading process allocates several areas in memory, storing Directmethod, Virtualmethod, Sfield, Ifield, respectively. This information is read from the data area of the Dex file. The fields field is defined as follows:
struct Field { classobject* clazz; //category//////// access Mark #endif};
After the class index is available, the actual load is done by Loadclassfromdex. First it reads the specific data of class, loads Directmethod, Virtualmethod, Ifield and Sfield, then allocates memory for the Classobject data structure and reads information about the Dex file. After loading, the loaded class is put into a hash table through the Dvmaddclasstohash function to facilitate the next lookup, and finally, by Dvmlinkclass, the class is searched for the superclass, and if there is an interface class, the corresponding interface class is loaded.
4.3 Dalvik interpreter
For any virtual machine, the interpreter is undoubtedly the core part, and all Java bytecode is interpreted and executed by the interpreter. Because the efficiency of the Dalvik interpreter is very important, Android has implemented the C language version and a variety of assembly language version of the interpreter. The interpreter is typically loop executed, requiring an ingress function call handler to execute the first instruction, and then each instruction executes with the next instruction, invoking the handler through the function pointer.
4.4 Memory Management
Garbage collection is the core of Dalvik virtual machine memory management. Only the garbage collection feature of the Dalvik virtual machine is described here. The performance of garbage collection affects the efficiency of the memory usage of a Java program to a great extent. The Dalvik virtual machine uses a commonly used mark-sweep algorithm that points to the Mark phase (tag out the active object), the sweep phase (reclaim garbage memory), and the optional compact phase (to reduce fragmentation in the heap). Android Memory Management Principles This article explains it in detail.
The first step in garbage collection is to tag the active object, because there is no way to identify the inaccessible objects so that all unmarked objects are garbage that can be reclaimed. When you do garbage collection, you need to stop the Dalvik virtual machine from running (except for garbage collection), so garbage collection is also known as STW (Stop-the-world). The Dalvik virtual machine maintains some state information during the run, including: registers saved by each thread, static fields in Java classes, local and global jni references, and all function calls in the JVM correspond to a corresponding C stack frame. Each stack frame may contain references to objects, such as local variables and parameters that contain object references. All of these reference information is added to a root collection and then, starting from the root collection, recursively finds objects that can be accessed from the root collection. As a result, the mark process is also called tracking, tracing all objects that can be accessed.
The second step in garbage collection is to reclaim memory. At the mark Stage, all the accessible collections of objects are available through the markbits bitmap, while the Livebits bitmap represents all of the allocated object collections. The difference between the livebits bitmap and the Markbits bitmap is the collection of all recyclable objects. The sweep stage calls free to release the memory to the heap.
On the underlying memory implementation, the Android system uses Msspace, a lightweight malloc implementation. In addition to creating and initializing a heap of memory for storing plain Java objects, Android also creates three additional memory heaps:
- "Livebits" (the bitmap index used to hold memory on the heap)
- "Markbits" (the bitmap index used to label the surviving object in GC)
- "Markstack" (traversing the label stack of the surviving object reference in the GC)
The virtual machine manipulates the GC memory heap through a global heapsource variable called GHS, while Heapsource can manage multiple heaps (heap) through the heaps array to meet the need to dynamically adjust the size of the GC memory heap. In addition Heapsource maintains a bitmap index named "Livebits" to track memory usage for each heap (heap). The remaining two data structures "Markstack" and "markbits" are used in the garbage collection phase.
"Livebits" maintains the memory information used on the heap, while the "Markbits" bitmap index points to the surviving object. A, C, F, G, h objects need to be preserved, so "markbits" points to them (the last H object is still in the labeling process, so there is no pointer pointing to it). The "Markstack" is the tag stack that keeps track of the objects being processed, such as F, G, and H, as they are tracked in the labeling process.
4.5 Dalvik Start-up process
Dalvik process management is dependent on the process architecture of Linux, such as creating a process for an application that uses the fork mechanism of Linux to replicate a process. Zygote is a virtual machine process and also an incubator of virtual machine instances, which is started by the Init process. Previous articles have detailed descriptions of this process: Android system boot analysis (init->zygote->systemserver->home activity). This is an analysis of the process associated with Dalvik virtual machine startup.
The Androidruntime class mainly does the following things:
- Call STARTVM to create a Dalvik virtual machine, JNI_CREATEJAVAVM actually create and initialize the virtual machine instance
- Call Startreg to register the Jni method of the Android core class
- Entering the Java layer through the zygote process
In Jni, Dvmcreatejnienv creates and initializes a JNI environment for the current thread, which is a Jnienvext object. Finally, call Dvmstartup to initialize the Dalvik virtual machine instance that you created earlier. The function Dvminitzygote invokes the system's Setpgid to set the current process, which is the process group ID of the zygote process. When this step is complete, the creation and initialization of the Dalvik virtual machine is complete.
5 Android Start-up
- Start power, load bootloader to ram
- bootloader Boot
- Linux Kernel Boot
- Init process Creation
- Init fork out zygote process, zygote process create virtual machine, create system service
- Android Home Launcher Launcher
Reference:
The Insider of Android technology
Dalvik Virtual Machine Brief introduction and Learning Plan
Deep understanding of Android (ii): Java Virtual machine Dalvik
Dalvik Virtual Memory Management II--garbage collection
Analysis of startup process of Dalvik virtual machine
Http://www.cnblogs.com/lao-liang/p/5111399.html
Understanding Android Virtual Machine Architecture (RPM)