Article directory
1. The execution flow of the method
raw java code
public class Demo3_1 {
public static void main(String[] args) {
int a = 10;
int b = Short.MAX_VALUE + 1;
int c = a + b;
System.out.println(c);
}
}
compiled bytecode file
[root@localhost ~]# javap -v Demo3_1.class
Classfile /root/Demo3_1.class
Last modified Jul 7, 2019; size 665 bytes
MD5 checksum a2c29a22421e218d4924d31e6990cfc5
Compiled from "Demo3_1.java"
public class cn.itcast.jvm.t3.bytecode.Demo3_1
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #7.#26 // java/lang/Object."<init>":()V
#2 = Class #27 // java/lang/Short
#3 = Integer 32768
#4 = Fieldref #28.#29 //
java/lang/System.out:Ljava/io/PrintStream;
#5 = Methodref #30.#31 // java/io/PrintStream.println:(I)V
#6 = Class #32 // cn/itcast/jvm/t3/bytecode/Demo3_1
#7 = Class #33 // java/lang/Object
#8 = Utf8 <init>
#9 = Utf8 ()V
#10 = Utf8 Code
#11 = Utf8 LineNumberTable
#12 = Utf8 LocalVariableTable
#13 = Utf8 this
#14 = Utf8 Lcn/itcast/jvm/t3/bytecode/Demo3_1;
#15 = Utf8 main
#16 = Utf8 ([Ljava/lang/String;)V
#17 = Utf8 args
#18 = Utf8 [Ljava/lang/String;
#19 = Utf8 a
#20 = Utf8 I
#21 = Utf8 b
#22 = Utf8 c
#23 = Utf8 MethodParameters
#24 = Utf8 SourceFile
#25 = Utf8 Demo3_1.java
#26 = NameAndType #8:#9 // "<init>":()V
#27 = Utf8 java/lang/Short
#28 = Class #34 // java/lang/System
#29 = NameAndType #35:#36 // out:Ljava/io/PrintStream;
#30 = Class #37 // java/io/PrintStream
#31 = NameAndType #38:#39 // println:(I)V
#32 = Utf8 cn/itcast/jvm/t3/bytecode/Demo3_1
#33 = Utf8 java/lang/Object
#34 = Utf8 java/lang/System
#35 = Utf8 out
#36 = Utf8 Ljava/io/PrintStream;
#37 = Utf8 java/io/PrintStream
#38 = Utf8 println
#39 = Utf8 (I)V
{
public cn.itcast.jvm.t3.bytecode.Demo3_1();
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 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcn/itcast/jvm/t3/bytecode/Demo3_1;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=4, args_size=1
0: bipush 10
2: istore_1
3: ldc #3 // int 32768
5: istore_2
6: iload_1
7: iload_2
8: iadd
9: istore_3
10: getstatic #4 // Field
java/lang/System.out:Ljava/io/PrintStream;
13: iload_3
14: invokevirtual #5 // Method
java/io/PrintStream.println:(I)V
17: return
LineNumberTable:
line 8: 0
line 9: 3
3)常量池载入运行时常量池
4)方法字节码载入方法区
5)main 线程开始运行,分配栈帧内存
(stack=2,locals=4)
line 10: 6
line 11: 10
line 12: 17
LocalVariableTable:
Start Length Slot Name Signature
0 18 0 args [Ljava/lang/String;
3 15 1 a I
6 12 2 b I
10 8 3 c I
MethodParameters:
Name Flags
args
}
1.1 Load the constant pool into the runtime constant pool
First, the class where the main method is located will be loaded by the class loader of the JVM.
That is, the bytecode file is read into memory. The data in this part of the constant pool will be placed in the runtime constant pool of the memory.
Students who don’t know what a runtime constant pool is can take a look at this [JavaSE] Analysis of String and StringTable
Some relatively small numbers, such as 10, are not stored in the runtime constant pool, but are stored together with the bytecode instructions of the method.
Once this number exceeds the maximum value of an integer ( Short.MAX_VALUE
), it will be stored in the constant pool.
1.2 Load method bytecode into method area
Some bytecodes of the method will be placed in the method area
1.3 The main thread starts running and allocates stack frame memory
There are two things in the stack frame, namely the local variable table and the operand stack.
The size of these two things has been specified in the bytecode file.
Code:
stack=2, locals=4, args_size=1
That is, the operand stack is 2, and the local variable table is 4.
1.4 The execution engine starts to execute the bytecode
According to the bytecode file in the method area, the execution flow is as follows.
Executionbipush 10
, this instruction means to push a byte into the operand stack (its length will be filled with 4 bytes), and there are similar instructions
sipush
Push oneshort
onto the operand stack (its length will be padded to 4 bytes)ldc
Push oneint
onto the operand stackldc_w
Push onelong
into the operand stack (in two pushes, becauselong
it is 8 bytes)- The small numbers are stored together with the bytecode instructions, and
short
the numbers beyond the range are stored in the constant pool
Then, executeistore_1
, the meaning of this forest is to store in the local variable tableslot 1
ldc #3
, this instruction loads data from the constant pool #3
into the operand stack
istore2
, and then place 32768 in the operand stack in slot 2 of the local variable table.
iload1 与 iload2
The instruction is to place the data in the No. 1 and No. 2 positions of the local variable table into the operand in sequence
isadd
, this instruction corresponds to the addition operation, the execution engine will execute it add
, and two variables will pop up from the operand stack. add
After the execution engine completes the operation, it will be pushed into the operand stack again
istore 3
Then pop the variable in the operand stack and place it in position 3, that is, assign it to c
getstatic #4
, find a static object in the constant pool, load it into the operand, and then load 3
push the data in slot 3 into the operand, invokevirtual #5
the instruction is to find item #5 of the constant pool, locate the method java/io/PrintStream.println(I)
and generate a new stack frame, Pass the parameters and execute the bytecode of the new stack frame
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-B9AX35Ax-1678159317918)(https://lnnu-tuchuang.oss-cn-guangzhou.aliyuncs.com/img /image-20230307105849420.png)]
After execution, the stack frame is popped and the contents of the main operand stack are cleared.
Finally, return completes the call of the main method, pops up the main stack frame, and ends the program.
2. Condition judgment
The instruction for conditional judgment is shown in the figure below
[External link picture transfer failed, the source site may have an anti-theft link mechanism, it is recommended to save the picture and upload it directly (img-XCr9T3UI-1678159317919)(https://lnnu-tuchuang.oss-cn-guangzhou.aliyuncs.com/img /image-20230307110332183.png)]
It should be noted that byte, short, and char will be compared as int, because the operand stack is 4 bytes
2.1 Source code analysis
public class Demo3_3 {
public static void main(String[] args) {
int a = 0;
if(a == 0) {
a = 10;
} else {
a = 20;
}
}
}
0: iconst_0
1: istore_1
2: iload_1
3: ifne 12
6: bipush 10
8: istore_1
9: goto 15
12: bipush 20
14: istore_1
15: return
iconst_0
, get a constant of 0 and push it into the operand stackistore_1
, put this element of the operand stack in position 1 of the local variable table, that is, assign a value of 0iload_1
, and then push the value of a onto the operand stackifne 12
, to judge whether==
0- If
!=
0, then jump to the middle area of the 12-line bytecode instructionbipush 20
, that is, push 20 into the operand stack,istore_1
and assign a to 20. - If it is
==
0, it is to continue to executebipush 10
andistore_1
, assign a to 10, andgoto 15
when executing, skip to line 15return
- If
3. Loop control instruction
The loop control instruction is actually similar to the conditional judgment, but it uses goto
the loop
3.1 Source code analysis
public class Demo3_4 {
public static void main(String[] args) {
int a = 0;
while (a < 10) {
a++;
}
}
}
0: iconst_0
1: istore_1
2: iload_1
3: bipush 10
5: if_icmpge 14
8: iinc 1, 1
11: goto 2
14: return
iconst_0
Andistore_1
, assign a to 0.iload_1
Push the value of a onto the operand stackbipush 10
, push 10 onto the operand stackif_icmpge 14
, to judge whether the two ints are true>=
, if not, then jump to the 14th line of instructions- If it is established, then
iinc 1, 1
the No. 1 position of the local variable table is incremented by 1, and thengoto 2
continues to jump back to the No. 2 position.