操作栈(Operand Stack)
- 每一个独立的栈帧包含了局部变量表以外,
操作栈
,也可以称为表达式栈(Expression Stack)
- 操作数栈,在方法执行过程中,根据
字节码指令
,往栈中存储数据或提取数据
,也就是入栈(push)/出栈(pop)
某些字节码指令将值压入操作数栈,其余的字节码指令将操作数取出栈
,使用他们后再将他们压入栈中,主要用于保存计算过程中的中间结果
,同时作为计算过程中变量临时的存储空间
- 比如:执行复制、交换、求和等操作。
是JVM执行引擎的一个工作区
,当一个方法刚开始执行
的时候,一个新的栈帧也会随之被创建出来
,这个方法的操作数栈是空的
。
- 每一个操作舒展都会拥有一个明确的栈深度用于存储数值,其所需的深度在编译器就确定好了,保存在方法的Code中,为Max_stack的值。
栈中的任何一个元素都是可以是任意的Java数据类型,
32bit的类型只占用一个栈单位深度
64bit的类型占用两个栈单位深度
操作数栈并非采用访问索引的方式进行数据访问的,只能通过标准的入栈和出栈操作来完成一次数据的访问
。
- 如果调用的方法带有返回值的化,其返回值会被压入当前
栈桢中的操作数栈中
,并更新PC计数器的下一条需要执行的字节码 指令
操作数栈中的元素的数据类型必须和字节码ade指令的序列严格匹配
,这又编译器在编译期间进行验证
,同时在类加载过程中的类检验阶段的数据流分析阶段要再次验证
。
- 另外,Java虚拟机的解释引擎是基于栈的执行引擎,其中的栈指值得就是操作数栈
前面提过,基于栈式架构的虚拟机所使用的零值地址指令更加紧凑
,但完成一项操作的时候,必须需要使用更多的入栈和出栈的指令,这也就意味将需要更多的指令指派(instruction dispatch)的次数和内存的读写次数
。
由于操作数栈的存储是在内存中的
,因此频繁的执行内存读写操作必然影响执行速度
,为了解决这个问题,Hotspot JVM的设计者提示了栈顶缓存计数
,将栈顶元素完全缓存在物理cpu寄存器中,以这种方式来降低对内存的读写次数,提升执行引擎的执行效率。