理解 JVM Stack 栈帧 Frame

≡放荡痞女 提交于 2020-04-09 03:58:31

前置知识

  • JVM运行时数据区
  • 栈帧的组成

虚拟机栈 与 栈帧

虚拟机栈(JVM Stack),由 栈帧 Frame 组成。 Frame - 每个方法对应一个栈帧, 包括以下部分:

  • Local Variable Table (局部变量表)
  • Operand Stack(操作数栈) 操作数栈(Operand Stack)也常称为操作栈,它是一个后入先出(Last In FirstOut,LIFO)栈。 同局部变量表一样,操作数栈的最大深度也在编译的时候写入到Code属性的max_stacks数据项中。
  • Dynamic Linking(动态链接) 动态链接是一个将符号引用解析为直接引用的过程。
  • return address(返回地址) a() -> b(),方法a调用了方法b, b方法的返回值放在什么地方 方法退出时会做的操作:
    • 恢复上一个方法(调用者的栈帧)的Local Variable Table(局部变量表)和Operand Stack(操作数栈)
    • 将返回的变量压入 上一个方法(调用者的栈帧)的Operand Stack(操作数栈)
    • 调整 Program Counter Register (PC, 程序计数器) 的值为 当前帧的返回地址
    • 当前栈帧弹出JVM Stack 栈,
    • 执行Program Counter Register (PC, 程序计数器)指向的指令

理解JVM栈帧

用两个代码来帮助理解。

  public static void main(String[] args) {
    int i = 8;
    i = i++;
    System.out.println(i);
  }
  public static void main(String[] args) {
    int i = 8;
    i = ++i;
    System.out.println(i);
  }

这里两个代码分别打印什么呢?

结果是 9 和 8 。 为什么呢??

我们使用字节码原语来解析一下。

这里用到我们的一个IDEA 插件: jclasslib Bytecode viewer

i= i++

  • 0 bipush

  • 2 istore_1 ---> int i = 8;

  • 3 iload_1

  • 4 iinc 1 by 1 --> 完成 i++

  • 7 istore_1 --> i = i++;

i = ++i

前面都是一样。 区别只在于 这个是先 iinc 1 by 1 后 iload_1

  • 6 iload_1 --> 完成 ++i

  • 7 istore_1 --> i = ++i;

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!