专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 hot资讯 Java虚拟机栈是什么

Java虚拟机栈是什么

更新时间:2021-05-17 11:13:18 来源:动力节点 浏览668次

何为虚拟机栈

虚拟机栈的栈元素是栈帧,当有一个方法被调用时,代表这个方法的栈帧入栈;当这个方法返回时,其栈帧出栈。因此,虚拟机栈中栈帧的入栈顺序就是方法调用顺序。什么是栈帧呢?栈帧可以理解为一个方法的运行空间。它主要由两部分构成,一部分是局部变量表,方法中定义的局部变量以及方法的参数就存放在这张表中;另一部分是操作数栈,用来存放操作数。我们知道,Java 程序编译之后就变成了一条条字节码指令,其形式类似汇编,但和汇编有不同之处:汇编指令的操作数存放在数据段和寄存器中,可通过存储器或寄存器寻址找到需要的操作数;而 Java 字节码指令的操作数存放在操作数栈中,当执行某条带 n 个操作数的指令时,就从栈顶取 n 个操作数,然后把指令的计算结果(如果有的话)入栈。因此,当我们说 JVM 执行引擎是基于栈的时候,其中的“栈”指的就是操作数栈。举个简单的例子对比下汇编指令和 Java 字节码指令的执行过程,比如计算 1 + 2,在汇编指令是这样的:

mov ax, 1 ;把 1 放入寄存器 ax add ax, 2 ;用 ax 的内容和 2 相加后存入 ax

而 JVM 的字节码指令是这样的:

iconst_1 //把整数 1 压入操作数栈 iconst_2 //把整数 2 压入操作数栈 iadd //栈顶的两个数相加后出栈,结果入栈

由于操作数栈是内存空间,所以字节码指令不必担心不同机器上寄存器以及机器指令的差别,从而做到了平台无关。

注意,局部变量表中的变量不可直接使用,如需使用必须通过相关指令将其加载至操作数栈中作为操作数使用。比如有一个方法 void foo(),其中的代码为:int a = 1 + 2; int b = a + 3;,编译为字节码指令就是这样的:

iconst_1 //把整数 1 压入操作数栈 iconst_2 //把整数 2 压入操作数栈 iadd //栈顶的两个数出栈后相加,结果入栈;实际上前三步会被编译器优化为:iconst_3 istore_1 //把栈顶的内容放入局部变量表中索引为 1 的 slot 中,也就是 a 对应的空间中 iload_1 // 把局部变量表索引为 1 的 slot 中存放的变量值(3)加载至操作数栈 iconst_3 iadd //栈顶的两个数出栈后相加,结果入栈 istore_2 // 把栈顶的内容放入局部变量表中索引为 2 的 slot 中,也就是 b 对应的空间中 return // 方法返回指令,回到调用点

需要说明的是,局部变量表以及操作数栈的容量的最大值在编译时就已经确定了,运行时不会改变。并且局部变量表的空间是可以复用的,例如,当指令的位置超出了局部变量表中某个变量 a 的作用域时,如果有新的局部变量 b 要被定义,b 就会覆盖 a 在局部变量表的空间。

盗用别人的图以让大家对虚拟机栈有个直观的认识(其中小字体 Stack 指的的是虚拟机栈,Frame 是栈帧,Local variables 是局部变量表,Operand Stack 是操作数栈):

Java虚拟机栈是什么

以上就是动力节点小编介绍的"Java虚拟机栈是什么",希望对大家有帮助,如有疑问,请在线咨询,有专业老师随时为您服务。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>