JVM-执行流程示例

深度剖析:https://z.itpub.net/article/detail/A323358F7E35E224FD288ABBB1FD9BAE

原始 Java 代码:

1
2
3
4
5
6
7
8
public class Demo {	
public static void main(String[] args) {
int a = 10;
int b = Short.MAX_VALUE + 1;
int c = a + b;
System.out.println(c);
}
}

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 1

    ldc #3:从常量池加载 #3 数据到操作数栈
    Short.MAX_VALUE 是 32767,所以 32768 = Short.MAX_VALUE + 1 实际是在编译期间计算完成

    istore_2:将操作数栈顶数据弹出,存入局部变量表的 slot 2

    iload_1:将局部变量表的 slot 1 数据弹出,放入操作数栈栈顶

    iload_2:将局部变量表的 slot 2 数据弹出,放入操作数栈栈顶

    iadd:执行相加操作

    istore_3:将操作数栈顶数据弹出,存入局部变量表的 slot 3

    getstatic #4:获取静态字段

    iload_3

    invokevirtual #5

    • 找到常量池 #5 项
    • 定位到方法区 java/io/PrintStream.println:(I)V 方法
    • 生成新的栈帧(分配 locals、stack等)
    • 传递参数,执行新栈帧中的字节码
    • 执行完毕,弹出栈帧
    • 清除 main 操作数栈内容

    return:完成 main 方法调用,弹出 main 栈帧,程序结束

文章作者: GeYu
文章链接: https://nuistgy.github.io/2023/06/20/JVM-执行流程示例/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Yu's Blog