操作数栈
- 每一个独立的栈帧中除了包含局部变量表以外,还包含一个先进后出(last-in-first-out)的操作数栈,也可以称为表达式栈(Expression stack)。它在方法执行过程中根据字节码指令,往栈中写入数据或提取数据,即入栈、出栈。
- 操作数栈主要保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。某些字节码指令将值压入操作数栈,其余的字节码指令将操作数取出栈。使用之后再把结果压入栈比如执行复制、交换、求和等操作。
- 操作数栈就是JVM执行引擎的一个工作区,当一个方法执行时,一个新的栈帧会同时被创建,这个方法的操作数栈是空的。每一个操作数栈都拥有一个明确的栈深度用于存储数值,其所需的最大深度在编译期间就定义好了,保存在方法的code属性中,为max_stack的值。
- 栈中的任意元素都是可以任意的Java数据类型,32bit的类型占用一个栈单位深度,64bit的类型占用两个栈单位深度。操作数栈不是采用访问索引的方式来进行数据访问的,而是只能通过标准的入栈和出栈操作来完成一次数据访问。
- 操作数栈的元素类型必须与字节码指令的序列严格匹配,编译器在编译期间进行验证,同时在类加载过程中的类检验阶段的数据流分析阶段要再次验证。如果被调用的方法有返回值,其返回值将会被压入当前栈帧的操作数栈中,并更新PC寄存器中下一条需要执行的字节码指令。
- 栈式架构的虚拟机所使用的零地址指令,使得完成一项操作需要更多的入栈和出栈操作指令,操作数是存储在内存中的,意味着有更加频繁的读写操作。HotSpot JVM为了解决这个问题,提出了栈顶缓存(TOS,Top-of-stack cashing)技术,将栈顶元素全部缓存在物理CPU的寄存器中,可以降低对内存的读写次数,提升执行引擎的执行效率。
欢迎批评指正,提出问题,谢谢!