Schematic diagram of Java Virtual Machine 4. JVM machine Instruction Set
0. Preface
The Java virtual machine runs binary machine code like a real computer. java source code compiled. the class file is the binary machine code that the Java Virtual Machine can recognize. Java can identify the information and machine commands in the class file and then execute these machine commands. So how does the Java Virtual Machine run these binary machine codes? This article uses a very simple example to show you how the Java Virtual Machine runs the machine code and how it works.
After reading this article, you will learn:
1. Java Virtual Machine for the runtime Virtual Machine Stack (JVM Stack) organization
2. How is the method calling process represented in JVM?
3. Basic JVM policy for executing a method
4. JVM machine instruction format
5. Execution Mode of machine commands-operations stack-based mode
1. Java Virtual Machine for the runtime Virtual Machine Stack (JVM Stack) organization
During running, the Java Virtual Machine allocates a virtual machine stack to each thread in the memory to indicate the running status and information of the thread. The elements in the Virtual Machine stack are called stack frames (JVM stack frames ), each stack frame indicates the call information of this method. As follows:
The above description may be a bit abstract. To give readers an intuitive feeling, we define a simple Java class and then execute this class to run it, analyzes the runtime information of the entire Java Virtual Machine step by step.
2. How is the method calling process represented in JVM?
We will define the simple class org. louis. jvm. codeset. Bootstrap. java with the main method as follows, and gradually analyze how the class is represented in JVM and how the method runs step by step:
Package org. louis. jvm. codeset;/*** simple JVM Principle Use Case * @ author louis **/public class Bootstrap {public static void main (String [] args) {String name = "Louis "; greeting (name);} public static void greeting (String name) {System. out. println ("Hello," + name );}}
When we compile Bootstrap. java into Bootstrap. class and run this program, the following steps are taken in the complex JVM running logic:
1. First, the JVM will first load the Bootstrap. class information to the Method Area in the memory.
Bootstrap. class contains constant pool information, method definitions, and binary machine commands implemented by compiled methods. All threads share a method zone, the Instruction Set for reading method definitions and methods.
2. Then, JVM will create a class for Bootstrap. Class on the Heap. An instance is used to represent a class instance of Bootstrap. class.
3. When the JVM starts to execute the main method, a stack frame will be created for the main method to indicate the entire execution process of the main method (this process will be detailed in the subsequent sections );
4. when the main method calls the greeting static method during execution, the JVM will create a stack frame for the greeting method, push to the top of the VM stack (this process will be detailed in later sections ).
5. After the greeting method is run, the greeting method is out of the stack and the main method continues to run;
The JVM method call process is implemented through stack frames. How is the method instruction executed? Before figuring out this, we should first understand what the method structure is for JVM.
We know that the JVM can recognize binary files in class files, which describe the definition of each method through a specific structure.
During the process of compiling Bootstrap. java, the JVM will determine the three information of each method while compiling the source code into a binary machine code:
1 ). the number of local variables that will be used during runtime (Role: When JVM creates a stack frame for the method, it creates a local variable table for the method in the stack frame, to store the local variable values of method commands during operation)
2 ). the maximum size of the operand stack required for executing machine commands (when JVM creates a stack frame for the method, it creates an operand stack for the method in the stack frame, make sure that instructions in the method can complete the work)
3). Number of parameters of the Method
After compilation, we can get the information of the main and greeting methods as follows:
Note: All the compiled information is stored in Bootstrap. the class file is stored in the format of this Class file. I have made a very detailed introduction to the definition of the Class file format in the previous articles, if you have read all the files, I believe you can "read" The class file. How to Understand the organization of methods and their corresponding machine codes in the class binary file, please refer to "Schematic diagram of Java Virtual Machine" 1.5. set of methods in the class file -- how the method is organized in the class file.
The process of running the main method by JVM:
1. Create stack frames for the main method:
The JVM parses the main method and finds that the number of local variables is 2 and the number of operand Stacks is 1. A Stack frame (VM Stack) is created for the main method ), and add it to the VM Stack:
2. Complete stack frame Initialization:
After the main stack frame is created, the stack frame will be pushed to the VM stack. Now there are two important steps to do:
A) Calculate the PC value.PC is the instruction counter. Its internal value determines which machine command should be executed by the JVM virtual machine next, and the machine command is stored in the method area, we need to point the PC value to the main method in the method area;
Initialize PC = the address of the main method instruction in the Method Area + 0;
B) initialize local variables.The main method has an input parameter (String [] args). JVM has provided a slot for it in the local variable table of the stack frame where main is located, we need to initialize the reference value of args to the local lighting table;
- Then the JVM starts to read the machine commands pointed to by the PC. As shown in, the command sequence of the main method:
12 10 4c 2b b8 20 12 b1
By using the JVM virtual machine instruction set specification, You can parse this command sequence into the following Java assembly language:
Machine commands |
Assembly Language |
Explanation |
Impact on Stack Frames |
0x12 0x10 |
Ldc #16 |
Push the reference of 16th constant pool items in the constant pool to the top of the operand stack. 16th items in the constant pool are CONSTANT_UTF-8_INFO items, representing the "Louis" String |
|
0x4c |
Astore_1 |
The top element of the stack of the operand stack goes out of the stack, and the value of the top element of the stack is assigned to the partial variable table element with index = 1.
This is equivalent to: name = "Louis ". |
|
0x2b |
Aload_1 |
Push the value of the index = 1 element in the local variable table to the top of the operand stack. |
|
0xb8 0x20 0x12 |
Invokestatic #18 |
0xb8 <喎?http: www.bkjia.com kf ware vc " target="_blank" class="keylink"> Vc3Ryb25nPrHtyr67 + counter = "0x12 = 18, operand 18 indicates pointing to 18th items of the constant pool, which is a symbolic reference of the main method: Org/louis/jvm/codeset/Bootstrap. greeting :( Ljava/lang/String;) V When JVM executes this statement, it will do the following: A). Verify the method symbol reference.It verifies the symbolic reference of this method and searches for the definition of this method in the constant pool according to this symbol rule. If the definition of this method is found, the resolution is successful. If it is a method greeting:(Ljava/lang/String;)V Not found. JVM will throw an error NoSuchMethodError B) Create a New stack frame for the new method call.Then, JVM will create a new stack frame (VM stack) for this method greeting, and create the corresponding size of the operand stack based on the size of the operand stack in greeting and the number of local variables; then, push the stack frame to the top of the VM stack. C). Update the value of the PC instruction counter.Record the value of the current PC program counter to the greeting stack frame. After the greeting operation is completed, the PC value can be restored. Update the PC value so that the next executed command address points to the start part of the greeting method command. This statement will pause the current main method and enable JVM to execute the greeting method. After the greeting method is executed, the PC program counter value will be restored and directed to the next command. |
|
0xb1 |
Return |
Return |
|
|
|
|
|
When the main method calls greeting (), JVM creates a stack frame for the greeting method to call the greeting method. The stack frame information is as follows:
The meaning of the machine code of the specific greeting method is shown in:
Machine commands |
Assembly Language |
Explanation |
Constant pool reference |
B2 20 1a |
Getstatic #26 |
Obtains the static domain of the specified class and pushes its value to the top of the stack. Push the 26th symbol references in the constant pool to the operand Stack: |
#26: // Field java/lang/System. out: Ljava/io/PrintStream; |
Bb 20 20 |
New #32 |
Create an object and push its reference value to the top of the stack. Create a java/lang/StringBuider instance and press it to the top of the stack. |
#32: // Class java/lang/StringBuilder |
59 |
Dup |
Copy the top value of the stack of the operand and insert it to the top of the stack. |
|
12 22 |
Ldc #34 |
Extract data from the runtime constant pool and push it into the operand Stack Copy the "Hello" String reference to the operand Stack |
#34: // String Hello, |
B7 20 24 |
Invokespecial #36 |
Call the superclass constructor, instance initialization method, and private method. The StringBuilder (String) constructor is called here, and the result is pushed to the top of the stack. |
#36: // Method java/lang/StringBuilder ." ":( Ljava/lang/String;) V |
2a |
Aload_0 |
Push the reference of the first local variable to the top of the stack. The first local variable reference of the current local variable table is "Louis", which pushes Louis to the top of the stack. |
|
B6 20 26 |
Invokevirtual #38 |
Call the superclass constructor, instance initialization method, and private method. The append (String) method of the StringBuilder instance, indicating: "Hello," + "Louis ". |
// Method java/lang/StringBuilder. append :( Ljava/lang/String;) Ljava/lang/StringBuilder; |
B6 20 2a |
Invokevirtual #42 |
Call the superclass constructor, instance initialization method, and private method. Call the toString () method of the StringBuilder instance and keep the result at the top of the stack. |
// Method java/lang/StringBuilder. toString :() Ljava/lang/String; |
B6 20 2e |
Invokevirtual #46 |
Call the superclass constructor, instance initialization method, and private method. Call the System. out. println (String) method. |
// Method java/io/PrintStream. println :( Ljava/lang/String;) V |
B1 |
Return |
End return |
|
|
|
|
|
3. Basic JVM policy for executing a method
Generally, for java method execution, the JVM assigns a local variable table and an operand Stack to the method in the Virtual Machine Stack (JVM Stack) of a specific thread, the median stored in the running process of the storage method.
Because JVM commands are stack-based, most of the commands are executed along with the output and inbound stacks of the operands. Therefore, when learning JVM machine commands, remember one thing:
The execution of each machine instruction has a full understanding of the mechanism of the impact on the operand stack and local variables, so that you can smoothly read the binary machine instruction in the class file.
The following is a simplified diagram of stack frame information. When analyzing JVM commands, I have a clear understanding of stack frames in my mind:
4. machine instruction formatThe so-called Machine commands are binary code that only machines can recognize. A machine command consists of two parts:
Note:
A). As shown in, the operation code of the JVM virtual machine is composed of one byte. That is to say, for the JVM virtual machine, the maximum number of commands is 2 ^ 8, that is, 256;
B ). in the operation code such as b2, bb, 59 .... and so on, it indicates a specific machine command. To facilitate our identification, it has the corresponding mnemonic: getstatic, new, dup .... this makes it easy for us to understand.
5. Execution Mode of machine commands-operations stack-based modeFor traditional physical machines, most of the machine instruction designs are registers, and several registers are set in the physical machine to store the value during the machine instruction operation, the number of registers and the number of supported commands determine the processing capability of the machine.
However, the mechanism designed by the Java Virtual Machine is not like this. The Java virtual machine uses the operand stack to store the values in the operation process of machine commands. All operations on the operands must follow the out-stack and In-stack rules. Therefore, in the Java Virtual Machine specification, you will find that many machine commands are related to the operations on the stack.
This article aims to introduce the running principle of jvm vm commands. If you want to learn more about the instruction set and precautions, please read the Java Virtual Machine Specification (Java Virtual Machine Specification) detailed definition of the machine instruction set.