Java Virtual machine
Java Virtual machine (Java VM) referred to as the JVM Java Virtual machine is an imaginary machine that is implemented by software simulations on a real computer. The Java Virtual machine has its own imaginary hardware, such as processor, stack, register, etc., and also has the corresponding instruction system. Let's take a look at some of the more important Java Virtual machine constructs:
1) JVM Registers
All CPUs contain register groups that are used to hold the system State and the information required by the processor. If a virtual machine defines more registers, it can get more information from it without having to access the stack or memory, which helps to improve the speed of operation. However, if the registers in the virtual machine are more than the actual CPU registers, it will take a large amount of time for the processor to use conventional memory to simulate registers when implementing the virtual machine, which will reduce the efficiency of the virtual machines. In this case, the JVM only sets the 4 most common registers. They are: PC program counter, optop operand stack top pointer, frame current execution environment pointer, VARs Pointer to the first local variable in the current execution environment, all registers are 32 bits. The PC is used to record program execution. Optop,frame and VARs are used to record pointers to the Java stack area.
2) JVM Stack structure
As a stack-based computer, the Java stack is the primary method by which the JVM stores information. When the JVM obtains a Java bytecode application, it creates a stack frame for each method of a class in the code to hold the state information for the method. Each stack frame includes the following three types of information: local variable execution environment operand stack local variables are used to store local variables in the methods of a class. The VARs register points to the first local variable in the variable table. The execution environment is used to hold the information required by the interpreter during the interpretation of Java bytecode. They are: The last called method, the local variable pointer, and the stack top and bottom pointer of the operand stack. The execution environment is a control center that executes a method. For example, if the interpreter is going to perform iadd (integer addition), it first finds the current execution environment from the frame register, then finds the operand stack from the execution environment, pops two integers from the top of the stack, and then pushes the result into the top of the stack. The operand stack is used to store the operands required for the operation and the results of the operation.
3) JVM Fragment recovery heap
The storage space required for an instance of the Java class is allocated on the heap. The interpreter assumes the task of allocating space for the class instance. After the interpreter has allocated storage space for an instance, it begins to record the use of the area of memory occupied by that instance. Once the object has been used, it is recycled into the heap. In the Java language, there is no other method to request and free memory for an object other than the new statement. The work of freeing and reclaiming memory is carried out by the Java operating system. This allows the designers of the Java Runtime system to determine the method of fragment reclamation themselves. In the Java interpreter and hot Java environment developed by Sun, fragment recycling is performed in the same way as a background thread. This not only provides good performance for the operating system, but also gives program designers the risk of controlling their memory usage.
4) JVM Storage area
The JVM has two types of storage: a constant buffer pool and a method area. A constant buffer pool is used to store class names, method and field names, and string constants. The method area is used to store the bytecode of the Java method. The specific implementation of these two storage areas is not explicitly specified in the JVM specification. This allows the storage layout of the Java application to be determined during operation, depending on how the platform is implemented. The JVM is a platform-independent specification that is defined for Java bytecode and is the basis for the independence of the Java platform. The current JVM still has some limitations and shortcomings that need to be further perfected, but the JVM's ideas are successful anyway. Comparative analysis: If the original Java program to think of our C + + original program, the Java original program compiled after the generated bytecode is equivalent to C + + original program compiled 80x86 machine code (binary program Files), the JVM virtual machine equivalent to 80x86 computer system, The Java interpreter is equivalent to 80X86CPU. The machine code is running on the 80X86CPU, and Java bytecode is running on the Java interpreter. The Java interpreter is equivalent to "CPU" running Java bytecode, but the "CPU" is implemented by software instead of hardware. The Java interpreter is actually an application under a particular platform. As long as the interpreter program under a specific platform is implemented, Java bytecode can be run through the interpreter program on the platform, which is the root of the Java cross-platform. Currently, not all platforms have a corresponding Java interpreter program, which is why Java does not work on all platforms, it can only run in the implementation of the Java Interpreter program platform.
Architecture diagram for Java virtual machines
Java Virtual machine lifecycle from boot to end, when the Java Virtual machine starts, in the following cases, the Java VM will end the life cycle:
1) implemented the System.exit () method
2) Normal execution of the program ends
3) The program encountered an exception or error during execution and terminated abnormally
4) the Java Virtual machine process terminates due to an operating system error
Java Virtual machine stack three zones
1) local variable area
Each Java method uses a fixed-size set of local variables. They are addressed by the word offset to the VARs register. Local variables are 32-bit. Long integers and double-precision floating-point numbers occupy two of the space of local variables, but are addressed by the index of the first local variable. (for example, a local variable with index n, if it is a double-precision floating-point number, it actually occupies the storage space represented by index N and n+1) The virtual machine specification does not require that the 64-bit value in the local variable be 64-bit aligned. The virtual machine provides instructions for loading the values in the local variable into the operand stack, as well as instructions for writing the values in the operand stack to local variables.
2) Operating Environment area
The information contained in the run environment is used for dynamic linking, normal method returns, and exception snapping.
3) Operand stack area
The machine instructions only take the operands from the operand stack, manipulate them, and return the results to the stack. The reason for choosing a stack structure is that the behavior of the virtual machine can be simulated efficiently on machines with only a few registers or non-universal registers, such as Intel486. The operand stack is 32 bits. It is used to pass parameters to the method and receive the result from the method, also to support the parameters of the operation, and to save the result of the operation. For example, the IADD directive adds two integers. The added two integers should be the top two characters of the operand stack. The two words are pressed into the stack by the previous instruction. These two integers are ejected from the stack, added together, and the result is pressed back into the operand stack.
Each raw data type has special instructions to perform the necessary operations on them. Each operand requires a storage location in the stack, except for long and double types, which require two positions. The operand can only be manipulated by an operator that is applicable to its type. For example, it is illegal to press into a number of two int types if they are treated as a long type. In Sun's virtual machine implementation, this restriction is enforced by the bytecode validator. However, there are a few operations (operator dupe and swap) that are used to manipulate the runtime data area regardless of type.
Local method Stack, when a thread calls a local method, it is no longer constrained by the structure and security constraints of the virtual machine, it can access both the run-time data area of the VM or the local processor and any type of stack. For example, the local stack is a C-language stack, and when the C program calls the C function, the parameters of the function are pressed into the stack in some order, and the result is returned to the calling function. When implementing a Java Virtual machine, the local method interface uses the C-language model stack, and its local method stack is scheduled and used exactly the same as the C language stack.
can represent a whole process of running a Java program
The running process of a Java virtual machine
The above is a detailed description of the various parts of the virtual machine, the following is a specific example to analyze its operation process.
The virtual machine is started by invoking the method of a specified class, main, and passed to main a string array parameter, causing the specified class to be loaded, linking other types used by the class, and initializing them. For example, a program:
Class HelloApp {public static void main (string[] args) {System.out.println ("Hello world!"); for (int i = 0; i < args.length; i++) {System.out.println (args[i]); } }}
After compiling, type in command-line mode: Java HelloApp run virtual machine
The Java Virtual machine will be started by calling HelloApp's method main, passing to main an array containing three strings "run", "virtual", "machine". Now we outline the steps that the virtual machine may take when executing the HelloApp.
Started trying to execute the main method of class HelloApp and found that the class was not loaded, that is, the virtual machine does not currently contain a binary representation of the class, and the virtual machine uses ClassLoader to try to find such a binary representation. If this process fails, an exception is thrown. After the class is loaded and before the main method is called, the class HelloApp must be linked to and initialized with other types. The link consists of three phases: inspection, preparation and resolution. The test examines the symbols and semantics of the loaded main class, prepares to create a static domain of the class or interface, and initializes these fields to the standard default values, and resolves the symbolic references that are responsible for checking the main class to other classes or interfaces, which is optional in this step. The initialization of a class is the execution of a static initialization function declared in a class and the initialization of a static domain. A class must have its parent class initialized before it is initialized. The whole process is as follows:
Java Virtual machine underlying structure