1. First look at the structure of the JVM runtime data area
- Thread exclusive: Each thread has its own space that is created and destroyed with the thread lifecycle.
- Thread sharing: All threads have access to this memory data, which is created and destroyed with the virtual machine GC.
- JVM stores loaded class information, constants, static variables, compiled code, and so on.
Method Area
- This is a logical area in the virtual machine specification.
- The implementation is based on different virtual machines.
- For example, HotSpot for oracle is in the permanent generation of the method area in java7, java8 is in the metadata space, and this area is managed through the GC mechanism.
Heap memory
- Heap memory can be divided into:
- Older generations
- Cenozoic era
- Eden
- From Survivor
- To Survivor
- Created at JVM startup to hold instances of objects.
- The garbage collection period mainly manages heap memory.If it is full, an OutOfMemoryError will appear.
VM Stack
- Each thread has a private space in this space.
- A thread stack consists of multiple stack frames.
- A thread executes one or more methods, one corresponding to a stack frame.
- The contents of the stack frame include: local variable table, operand stack, dynamic link, method return address, additional information, and so on.
- StackOverflowError is thrown if stack memory exceeds the default maximum of 1M.
Native Method Stack
- Similar to the virtual machine stack functionality, the virtual machine stack is prepared for the virtual machine to execute JAVA methods, and the local method stack is prepared for the virtual machine to use the Native local method.
- The VM specification does not specify a specific implementation, which is implemented by different VM vendors.
- The implementation of the virtual machine stack in the HotSpot virtual machine is the same as that of the local method stack.Similarly, StackOverflowError will be thrown when the size is exceeded.
Program Counter Register
- Records where the current thread executes the byte code, stores the byte code instruction address, and if the Native method is executed, the counter value is empty.
- Each thread has a private space in this space, which takes up little memory space.
- The CPU executes instructions from only one thread at a time.JVM multithreading switches and allocates CPU execution time in turn.In order to restore the correct execution location after thread switching, program counters are required.
2. Next, let's look at the byte code files that we often refer to
1. Get a test code first
public class Demo1 { public static void main(String[] args) { int x = 500; int y = 100; int a = x / y; int b = 50; System.out.println(a + b); } }
2. Compile and generate class files
# Compile javac Demo1.java # view file contents javap -v Demo1.class > Demo.txt
3. Next, let's see what the Demo.txt file is all about.
Official description of the class file ( https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.1)
Classfile /Users/shadowolf/Demo1.class Last modified 2019-11-7; size 414 bytes MD5 checksum ae6fa820973681b35609c75631cb255b Compiled from "Demo1.java" public class Demo1 minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #5.#14 // java/lang/Object."<init>":()V #2 = Fieldref #15.#16 // java/lang/System.out:Ljava/io/PrintStream; #3 = Methodref #17.#18 // java/io/PrintStream.println:(I)V #4 = Class #19 // Demo1 #5 = Class #20 // java/lang/Object #6 = Utf8 <init> #7 = Utf8 ()V #8 = Utf8 Code #9 = Utf8 LineNumberTable #10 = Utf8 main #11 = Utf8 ([Ljava/lang/String;)V #12 = Utf8 SourceFile #13 = Utf8 Demo1.java #14 = NameAndType #6:#7 // "<init>":()V #15 = Class #21 // java/lang/System #16 = NameAndType #22:#23 // out:Ljava/io/PrintStream; #17 = Class #24 // java/io/PrintStream #18 = NameAndType #25:#26 // println:(I)V #19 = Utf8 Demo1 #20 = Utf8 java/lang/Object #21 = Utf8 java/lang/System #22 = Utf8 out #23 = Utf8 Ljava/io/PrintStream; #24 = Utf8 java/io/PrintStream #25 = Utf8 println #26 = Utf8 (I)V { public Demo1(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=5, args_size=1 0: sipush 500 3: istore_1 4: bipush 100 6: istore_2 7: iload_1 8: iload_2 9: idiv 10: istore_3 11: bipush 50 13: istore 4 15: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 18: iload_3 19: iload 4 21: iadd 22: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 25: return LineNumberTable: line 3: 0 line 4: 4 line 5: 7 line 6: 11 line 7: 15 line 8: 25 } SourceFile: "Demo1.java"
Classfile
Classfile /Users/shadowolf/Demo1.class Last modified 2019-11-7; size 414 bytes MD5 checksum ae6fa820973681b35609c75631cb255b Compiled from "Demo1.java"
- Mainly records some file information, including file local address, file size, last update time, MD5 check, compilation source, etc.
public class Demo1
public class Demo1 minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER
-
This section describes some of the information compiled.
-
Major version: major version number, minor version: minor version number, below is the corresponding relationship of versions.
JDK Version major.minor version 1.1 45 1.2 46 1.3 47 1.4 48 1.5 49 1.6 50 1.7 51 1.8 52 - You can count down the rest of yourself.
-
Flags: Access flag.The following is a list of access flags and their explanations
Flag Name Flag Value Meaning ACC_PUBLIC 0x0001 Is it a public type ACC_FINAL 0x0010 Is declared final, only classes can be set ACC_SUPER 0x0020 Whether invokespecial byte code directives are allowed or not, this flag is true for classes compiled after JDK12 ACC_INTERFACE 0x0200 Flag this is an interface ACC_ABSTRACT 0x0400 Is Abstract type, true for interface or abstract class, false for other values ACC_SYNTHETIC 0x1000 Marks that this class is not user generated ACC_ANNOTATION 0x2000 Identify this is a comment ACC_ENUM 0x4000 Identify this is an enumeration
Constant pool
Constant pool: #1 = Methodref #5.#14 // java/lang/Object."<init>":()V #2 = Fieldref #15.#16 // java/lang/System.out:Ljava/io/PrintStream; #3 = Methodref #17.#18 // java/io/PrintStream.println:(I)V #4 = Class #19 // Demo1 #5 = Class #20 // java/lang/Object #6 = Utf8 <init> #7 = Utf8 ()V #8 = Utf8 Code #9 = Utf8 LineNumberTable #10 = Utf8 main #11 = Utf8 ([Ljava/lang/String;)V #12 = Utf8 SourceFile #13 = Utf8 Demo1.java #14 = NameAndType #6:#7 // "<init>":()V #15 = Class #21 // java/lang/System #16 = NameAndType #22:#23 // out:Ljava/io/PrintStream; #17 = Class #24 // java/io/PrintStream #18 = NameAndType #25:#26 // println:(I)V #19 = Utf8 Demo1 #20 = Utf8 java/lang/Object #21 = Utf8 java/lang/System #22 = Utf8 out #23 = Utf8 Ljava/io/PrintStream; #24 = Utf8 java/io/PrintStream #25 = Utf8 println #26 = Utf8 (I)V
-
Constant pool.
-
For a more detailed understanding of constant pools, check out the blog ( http://softlab.sdut.edu.cn/blog/subaochen/2018/12/java-class%E6%96%87%E4%BB%B6%E7%BB%93%E6%9E%84%EF%BC%9A%E5%B8%B8%E9%87%8F%E6%B1%A0/)
-
List the constants
type describe CONSTANT_utf8_info UTF-8 Encoded String CONSTANT_Integer_info Integer Literal Quantity CONSTANT_Float_info Floating Point Literal Quantity CONSTANT_Long_info Long Integer Literal Quantity CONSTANT_Double_info Double Precision Floating Point Literal Quantity CONSTANT_Class_info Symbolic references to classes or interfaces CONSTANT_String_info String Type Literal Quantity CONSTANT_Fieldref_info Symbolic reference to field CONSTANT_Methodref_info Symbolic references to methods in classes CONSTANT_InterfaceMethodref_info Symbolic references to methods in interfaces CONSTANT_NameAndType_info Symbolic references to fields or methods CONSTANT_MethodType_info Flag Method Type CONSTANT_MethodHandle_info Representation Handle CONSTANT_InvokeDynamic_info Represents a dynamic method call point
Construction method
public Demo1(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 1: 0
-
In Demo1, we did not write a constructor.
-
Thus, when no constructor is defined, there is an implicit parameterless constructor.
-
Descriptor: ()V ->The understanding of this is that the input is null and the return value is void
Entry function: main function
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=5, args_size=1 0: sipush 500 3: istore_1 4: bipush 100 6: istore_2 7: iload_1 8: iload_2 9: idiv 10: istore_3 11: bipush 50 13: istore 4 15: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream; 18: iload_3 19: iload 4 21: iadd 22: invokevirtual #3 // Method java/io/PrintStream.println:(I)V 25: return LineNumberTable: line 3: 0 line 4: 4 line 5: 7 line 6: 11 line 7: 15 line 8: 25
-
Let's look at the execution order of the entire program
-
0: sipush 500: Push 500 into the operand stack
Sequence Number Local variable table 0 args Operand stack 500 -
3: istore_1: Save 500 to local variable table 1
Sequence Number Local variable table 0 args 1 500 Operand stack -
4: bipush 100: Push 100 into the operand stack
Sequence Number Local variable table 0 args 1 500 Operand stack 100 -
6: istore_2: Save 100 to the location of local variable table 2
Sequence Number Local variable table 0 args 1 500 2 100 Operand stack -
7: iload_1, 8: iload_2: Push data from local variable locations 1 and 2 into the operand stack
Sequence Number Local variable table 0 args 1 500 2 100 Operand stack 100 500 -
9: idiv: divides and pushes the result into the operand stack
Sequence Number Local variable table 0 args 1 500 2 100 Operand stack 5 -
10: istore_3: Save 5 (500/100) to the location of local variable table 3
Sequence Number Local variable table 0 args 1 500 2 100 3 5 Operand stack -
11: bipush 50: Push 50 into the operand stack
Sequence Number Local variable table 0 args 1 500 2 100 3 5 Operand stack 50 -
13: iStore 4: Save 50 to the location of local variable table 4 |Sequence Number|Local Variable Table| | --- | --- | | 0 | args | | 1 | 500 | | 2 | 100 | | 3 | 5 | | 4 | 50 |
Operand stack -
15: getstatic #2 // Field java/lang/System.out: Ljava/io/PrintStream; #2 from the constant pool is pushed into the operand stack
Sequence Number Local variable table 0 args 1 500 2 100 3 5 4 50 Operand stack #2 -
18: iload_3: Push data from 3 locations in the local variable table (5) into the operand stack
Sequence Number Local variable table 0 args 1 500 2 100 3 5 4 50 Operand stack 5 #2 -
19: Iload 4: Push data (50) from 4 locations in the local variable table into the operand stack
Sequence Number Local variable table 0 args 1 500 2 100 3 5 4 50 Operand stack 50 5 #2 -
21: iadd: Adds the first two elements of the stack and pushes the execution result (50+5=55) into the operand stack
Sequence Number Local variable table 0 args 1 500 2 100 3 5 4 50 Operand stack 55 #2 -
22: invokevirtual #3 // Method java/io/PrintStream.println:(I)V: JVM creates a new stack frame based on the description of this method. The parameters of the method pop up from the operand stack and push into the virtual machine stack. The virtual machine stack then starts executing the top stack frame of the virtual machine stack.
-
25: return: Execution complete, return to continue the main method, return, main method end.
-
At this point, the execution of our entire main function is explained.
-
3. Look at the running analysis of the overall function
1. Load information into method area
2. JVM creates a thread to execute
3. Execute main function
- This section has been analyzed above and is not repeated here.