Class file contents:
The class file contains the byte code executed by the JAVA program, and the data is arranged in a compact format in the binary stream in the class file without any separators in between. There is a special 0xcafebabe (hexadecimal) flag at the beginning of the file
The diagram above shows the contents of a hexadecimal class file
This file has a complex format and is designed to be read by JVM. People need tools to view it.
The content includes: version, access flag, constant pool, current class, superclass, interface, field, method, property.
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 can access this area and create and destroy it with a virtual machine or GC.
Method area:
JVM stores loaded class information, constants, static variables, compiled code, and so on.
This is a logical partition in the virtual machine specification. The implementation is based on different virtual machines.
For example: HotSpot for oracle in java7, method area in permanent generation, java8 in metadata space, and GC mechanism to manage this space.
Heap memory:
It can also be subdivided into older generations, newer generations (Eden, From Survivor, To Survivor).
Created at JVM startup to hold instances of objects. The primary purpose of the garbage collector is to manage heap memory.
OutOfMemroyError appears when memory is full. This is detailed later in the memory model.
Virtual machine stack:
Prepared for the virtual machine to execute java methods
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.
Stack frame content: local variable table, operand stack, dynamic link, method return address, additional information, etc.
StackOverFlowError is thrown if stack memory exceeds the default maximum of 1M
Local method stack:
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 two are implemented in the same way in a HotSpot virtual machine. StackOverFlowError will also be thrown after exceeding size
Program counters: (Peogram 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 timer value is empty.
Each thread has a private space in this space, which takes up less memory space.
The CPU only executes instructions from one thread at a time. JVM multithreading switches and allocates CPU execution time in turn. After switching threads, program counters are needed to restore the correct execution location.
View Class file contents:
java source code:
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); } }
The console executes the following commands under the current java file directory:
To write. java source code, javac command compiled. Class file, use the javap command to parse the results, view the txt file parse content. Class parses as follows:
Class file parse content:
(1) Version number/access control:
public class Demo1 minor version: 0 //Minor version number major version: 52 //Major Version Number flags: ACC_PUBLIC, ACC_SUPER //Access Flag
Version number rules: JDK5, 6, 7. 8 for each
Version number when jvm compiles source code
Access Flag:
(2) Constant pool
This type of information contains static constants that can be determined after compilation. The contents are as follows:
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
You can compare tables one to one.
(3) Construction methods:
In the Deme1 example, we did not write a constructor.
As you can see, without a custom constructor, there is an implicit parameterless constructor.
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
(4) Main method of program entry:
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
Describes the method:
(1) Access control:
flags: ACC_PUBLIC, ACC_STATIC
(2) Number of local variables, number of parameters, and method corresponding to the depth of the operand stack in the stack frame:
stack=3, locals=5, args_size=1
(3) The JVM execution engine executes the compiled scripts of these sources. javap is translated as an operator, and the class file stores instructions. The preceding number is the offset (in bytes), according to which JVM distinguishes different instructions. You can compare the JVM script table.
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
Interested partners can interpret the JVM script table as a comparison.
How exactly does this Demo1 work?
Program Full Run Analysis:
Load class information is stored in the method area. Method areas can hold different classes of information
(2) JVM creates a thread to execute code. To create a thread, you need to allocate space on the virtual machine stack, program counters, and so on. The Demo1 case is pure java code and does not involve local methods, so there is no need to allocate space on the local method stack. This is the thread exclusive space mentioned earlier. (
Demo1 has five local variables, and variable 0 is the method parameter args
Program counters, which open up a space for the current thread to record where the current thread executes code, that is, the sequence number it executes. When multithreaded switching occurs, the program counter reverts to the execution location of which thread the cpu executes.
Virtual Machine Stack: Opens up a stack space for the current thread, one thread corresponds to one stack, one stack consists of multiple stack frames, and one stack frame corresponds to the corresponding operation of a method. Threads are constantly executing one or more methods, so a thread corresponds to one or more stack frames.
Other stack frame information, interesting little partners look up by themselves.
Rules for running programs: code is converted to script, and jvm is executed according to the script.
Execution steps:
Initialization: 5 local variables (code proceeds), variable 0 is the location of method parameter args method parameter corresponding to local variable table 0
0: sipush500
Program counter: 0, push 500 into the operand stack
3: istore_1
Remove the top content of the operand stack, 500, to the location of the local variable table 1
4: bipush 100
Push 100 into the operand stack
6: istore_2
Remove the top content of the operand stack, that is, 100, and save it to the location of the local variable table 2
Contrast Demo1's source code and start
7: iload_1
Read local variable 1 and press into the operand stack.
8: iload_2
Read local variable 2 and press into the operand stack.
9: idiv
Two int s at the top of the stack are counted out and divided. The result is put on the stack, 500/100=5
10: iload_3
Remove the top content of the operand stack, 5, to the location of the local variable table 3
11: bipush 50
Push 50 on the operand stack
13: istore_4
Remove the top of the operand stack, or 50, and save it to local variable table 4
15:getstatic#2
Gets the value of a class or interface field and pushes it into the operand stack.
#2 corresponds to Fieldref #15.#16
Constant pools of this class:
18: iload_3
Read local variable 3 and press into the operand stack.
19: iload_4
Read the local variable 4 and press into the operand stack.
21:iadd
Remove the top two int types 50 and 5 from the operand stack to perform an addition operation. Result 55 is pushed into the operand stack.
22: invokevirtual #3
Starting a new method call, the stack frame of the original main method does not run, and the program counter of the main method does not run. Start executing new method stack frame.
Execute the new method stack and return to the main method stack frame execution. (JVM-controlled process)
25:return
void method returns, main method execution ends
Summary: This execution process is actually the java program running process, which is to manipulate the information in our local variable tables, operand stacks, and so on, to achieve the effect of the final program running.
Concluding remarks of this chapter:
This chapter explains in detail the core logic of the JVM. (
Runtime Data Area
Some content of the stack
Some content of stack frame
The execution of a script
The underlying principle of JVM operation: how do threads schedule? How to complete the function according to the stack of operands and program counters.
Different operating systems have different JVM implementations, so why JAVA can "write one thing, run everywhere"
It's almost like mastering the logic of how programs run. A deeper look at openJDK