聊聊栈帧中的局部变量表和操作数栈

前置阅读【图解JVM内存模型及JAVA程序运行原理】:https://developer.aliyun.com/article/1218034?utm_content=g_1000372435 

本文内容和【图解JVM内存模型及JAVA程序运行原理】一文中的“程序样例执行详解”相关。

 

代码示例:

public int operandStackExample(int a, int b) {
    int c = a * b;
    int d = a + b;
    return c - d;
}
  • 操作数栈执行过程:
  1. 将参数 a 压入操作数栈中,操作数栈:[a]。
  2. 将参数 b 压入操作数栈中,操作数栈:[a, b]。
  3. 执行乘法操作,弹出操作数栈顶的两个元素 a 和 b,计算 a * b 的结果 c,将结果 c 压入操作数栈中,操作数栈:[c]。
  4. 将参数 a 压入操作数栈中,操作数栈:[c, a]。
  5. 将参数 b 压入操作数栈中,操作数栈:[c, a, b]。
  6. 执行加法操作,弹出操作数栈顶的两个元素 a 和 b,计算 a + b 的结果 d,将结果 d 压入操作数栈中,操作数栈:[c, d]。
  7. 执行减法操作,弹出操作数栈顶的两个元素 c 和 d,计算 c - d 的结果,将结果压入操作数栈中,操作数栈:[c-d]。
  8. 将操作数栈顶的值返回给方法调用者。

总结:在这个例子中,操作数栈的完整执行过程包括将参数和临时数据压入栈中,执行计算操作,弹出栈顶元素,将计算结果压入栈中,最终将栈顶元素返回给方法调用者。

 

  • 局部变量表执行过程:
  1. 方法开始执行时,创建局部变量表,分配足够的空间存储局部变量。在这个例子中,局部变量表有 4 个槽,分别存储参数 a、参数 b、局部变量 c 和局部变量 d。
  2. 将参数 a 的值存入局部变量表的第 0 个槽中。
  3. 将参数 b 的值存入局部变量表的第 1 个槽中。
  4. 计算 a * b 的结果,并将结果存入局部变量表的第 2 个槽(局部变量 c)。
  5. 计算 a + b 的结果,并将结果存入局部变量表的第 3 个槽(局部变量 d)。
  6. 从局部变量表中取出 c 和 d 的值,计算 c - d 的结果,并将结果压入操作数栈中。
  7. 将操作数栈顶的值返回给方法调用者。

总结:在这个例子中,局部变量表的完整执行过程包括创建局部变量表,将参数和局部变量存入表中,读取表中的值进行计算,最终将计算结果压入操作数栈中。

 

  • 总结:

  局部变量表和操作数栈在 JVM 中分别有不同的作用:

  1. 局部变量表:局部变量表用于存储方法的参数和局部变量,包括基本数据类型和对象引用。它的作用是提供一个临时的存储区域,用于在方法执行过程中存储和访问方法的参数和局部变量。

  2. 操作数栈:操作数栈用于存储方法执行过程中的临时数据,包括基本数据类型和对象引用。它的作用是提供一个临时的存储区域,用于在方法执行过程中进行计算和操作。

因为局部变量表和操作数栈在结构和用途上有明显的区别,所以不能用局部变量表替代操作数栈。局部变量表主要用于存储方法的参数和局部变量,而操作数栈主要用于存储方法执行过程中的临时数据。如果将操作数栈的功能转移到局部变量表中,会导致局部变量表的使用变得复杂,而且会增加 JVM 的实现难度。因此,在 JVM 中,局部变量表和操作数栈都是必不可少的。

 

posted @ 2023-05-24 21:03  机械公敌  阅读(129)  评论(0编辑  收藏  举报