运行时数据区-虚拟机栈-操作数栈(Operand Stack)

操作数栈(Operand Stack)

  • 每一个独立的栈帧中除了包含局部变量表,还包含了一个后进先出(Last-In-Last-Out)的操作数栈,也可以称之为表达式栈(Expression Stack)
  • 操作数栈,在方法执行的过程中,根据字节码指令,往栈中写入数据或者提取数据,即入栈(push)、出栈(pop)
    • 某些字节码指令将值压入操作数栈,其余的字节码指令将操作数取出栈,使用后再把结果压入栈
    • 比如:执行复制、交换、求和等操作
  • 如果被调用的方法有返回值的话,其返回值将会被压入当前的操作数栈中,并更新PC寄存器中下一条需要执行的字节码指令
  • 操作数栈中元素的数据类型必须与字节码指令的序列严格匹配,这由编译器在编译期间进行验证,同时在类加载过程中的类检验阶段的数据流分析阶段再次校验
  • 另外我们说的Java虚拟机的解释引擎是基于栈的执行引擎,其中的栈指的就是操作数栈
  • 操作数栈,主要用于保存计算过程的中间结果,同事作为计算过程中变量临时的存储空间
  • 操作数栈就是JVM执行引擎的一个工作区,当一个新的方法开始执行的时候,一个新的栈帧随之被创建,这是该方法的操作数栈是空的
  • 每一个操作数栈都会有一个明确的栈深度用于存储数值,其所需的最大深度在编译期就定义好了,保存在Code属性中,为stack的值
  • 栈中的任何一个元素都是可以任意的Java数据类型
    • 32bit的类型占用一个栈单位深度
    • 64bit的类型占用两个栈单位的深度
  • 操作数栈并非采用索引的方式来访问数的,而是只能通过标准的入栈(push)和出栈(pop)操作来完成一次数据的访问

 

代码演示

非常简单的一段代码,申明一个方法testAddOperand方法,返回在方法中申明了几个变量:i、j、k,右边是jclasslib编译后的字节码(IDEA安装jclasslib插件即可)

通过javap -verbose OperandStackTest.class我们就能查看到方法testAddOperand的操作数栈的最大深度为2,局部变量表的值为4(我们只申明了3个,但是在非静态的方法中还有一个this指向当前对象的变量,所以这里的local=4)

 

操作步骤:

bipush,将15压入操作数栈的栈顶,此时pc寄存器指向0

 

  istore_1操作,将操作数栈中栈顶15弹出,放到局部变量表中,位置为1,此时pc寄存器在2的位置

 

  bipush 操作,将8压入操作数栈的栈顶,此时pc寄存器指向3

 

  istore_2操作,将操作数栈中栈顶8弹出,放到局部变量表中,位置为2,此时pc寄存器在5的位置

 

 iload_1, iload_2,iadd操作:将局部变量表中位置1和位置2的数值取出进行一个加操作,将结构压入操作数栈,此时pc寄存器8的位置

 

istore_3操作:将操作数栈栈顶的23加载道局部变量表3的位置,此时pc寄存器9的位置

 

最后该方法没有返回值,retrun结束

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值