- 每个线程在创建时都会创建一个虚拟机栈,其内部保存一个个栈帧,对应一次次的Java方法调用
- 是线程私有的
作用:主管Java程序的运行,它保存方法的局部变量,部分结果,并参与方法的调用和返回
栈是不存在垃圾回收的问题的
栈的存储单位:栈帧
线程上正在执行的每个方法都各自对应一个栈帧,栈帧是一个内存区块,是一个数据集。
栈帧中存着:局部变量,操作数栈,动态链接,方法返回地址+一些附加消息
- 局部变量表
-
定义为一个数字数组,主要是存储方法参数和定义在方法体内的局部变量
-
最基本的存储单元是变量槽(slot)
-
如果当前帧是由构造方法或者实例方法创建的,那么该对象引用this将会存放在index为0的slot处
-
如果需要访问局部变量表中的一个64bit局部变量时,只需要使用前一个索引即可
-
-
-
操作数栈
主要用于保持计算过程的中间结果,同时作为计算过程中变量的临时存储空间 栈顶缓存技术
由于操作数是存储在内存中的,因此频繁的执行内存读写操作必然会影响执行速度。为此
HotSpot JVM的设计者们提出了栈顶缓存技术:将栈顶元素全部缓存在物理CPU的寄存器中,以此降低对内存的读写次数 - 动态链接
大部分字节码指令在执行时都是需要常量池的访问,每个栈帧内部都包含一个指向运行时常量池中该栈帧所属方法的引用。常量池的作用就是为了提供一些符号和常量,便于指令的识别
相关问题
Java 虚拟机栈会出现两种错误:
- 栈溢出情况 StackOverflowError
通过-Xss设置栈的大小;
- OutOfMemoryError(OMM当整个内存空间不足,再进行扩容操作出现的情况)
Error | GC | |
程序计数器 | × | × |
虚拟机栈 | √ | × |
本地方法栈 | √ | × |
堆 | √ | √ |
方法区 | √ | √ |
调整栈的大小能保证不出现溢出情况吗?
—不能
分配的栈内存越大越好吗?
—整个空间有限,会挤占其它内存结构的空间
垃圾回收是否会涉及到虚拟机栈?
—不会