深度剖析:https://z.itpub.net/article/detail/A323358F7E35E224FD288ABBB1FD9BAE
原始 Java 代码:
1 | public class Demo { |
javap -v Demo.class:省略
常量池载入运行时常量池
方法区字节码载入方法区
main 线程开始运行,分配栈帧内存:(操作数栈stack=2,局部变量表locals=4)
执行引擎开始执行字节码
bipush 10
:将一个 byte 压入操作数栈(其长度会补齐 4 个字节),类似的指令- sipush 将一个 short 压入操作数栈(其长度会补齐 4 个字节)
- ldc 将一个 int 压入操作数栈
- ldc2_w 将一个 long 压入操作数栈(分两次压入,因为 long 是 8 个字节)
- 这里小的数字都是和字节码指令存在一起,超过 short 范围的数字存入了常量池
istore_1
:将操作数栈顶数据弹出,存入局部变量表的 slot 1ldc #3
:从常量池加载 #3 数据到操作数栈
Short.MAX_VALUE 是 32767,所以 32768 = Short.MAX_VALUE + 1 实际是在编译期间计算完成istore_2
:将操作数栈顶数据弹出,存入局部变量表的 slot 2iload_1
:将局部变量表的 slot 1 数据弹出,放入操作数栈栈顶iload_2
:将局部变量表的 slot 2 数据弹出,放入操作数栈栈顶iadd
:执行相加操作istore_3
:将操作数栈顶数据弹出,存入局部变量表的 slot 3getstatic #4
:获取静态字段iload_3
:invokevirtual #5
:- 找到常量池 #5 项
- 定位到方法区 java/io/PrintStream.println:(I)V 方法
- 生成新的栈帧(分配 locals、stack等)
- 传递参数,执行新栈帧中的字节码
- 执行完毕,弹出栈帧
- 清除 main 操作数栈内容
return:完成 main 方法调用,弹出 main 栈帧,程序结束