JVM中栈的详解

一、什么是栈

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

主管程序运行,生命周期和线程同步,线程结束,栈内存就释放了。不存在垃圾回收问题

存放的类型:8种数据类型、对象的引用、实例的方法
JVM中栈的详解_第1张图片

二、栈和队列

栈:先进后出,后进先出
队列:先进先出(FIFO)

三、栈帧

栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素。

①栈帧位置

JVM中栈的详解_第2张图片

②栈帧内存

一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响,而仅仅取决于具体的虚拟机实现。

③栈帧结构

局部变量表(Local Variable Table)

在编译程序代码的时候就可以确定栈帧中需要多大的局部变量表,具体大小可在编译后的 Class 文件中看到。局部变量表的容量以 Variable Slot(变量槽)为最小单位,每个变量槽都可以存储 32 位长度的内存空间。在方法执行时,虚拟机使用局部变量表完成参数值到参数变量列表的传递过程的,如果执行的是实例方法,那局部变量表中第 0 位索引的 Slot 默认是用于传递方法所属对象实例的引用(在方法中可以通过关键字 this 来访问到这个隐含的参数)。其余参数则按照参数表顺序排列,占用从 1 开始的局部变量 Slot。基本类型数据以及引用和returnAddress(返回地址)占用一个变量槽,long 和 double 需要两个。

操作数栈(Operand Stack)

同样也可以在编译期确定大小。
Frame 被创建时,操作栈是空的。操作栈的每个项可以存放 JVM 的各种类型数据,其中 long 和 double 类型(64位数据)占用两个栈深。
方法执行的过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈和入栈操作(与 Java 栈中栈帧操作类似)。操作栈调用其它有返回结果的方法时,会把结果 push 到栈上(通过操作数栈来进行参数传递)。

动态链接(Dynamic Linking)

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态链接。在类加载阶段中的解析阶段会将符号引用转为直接引用,这种转化也称为静态解析。另外的一部分将在运行时转化为直接引用,这部分称为动态链接。

返回地址(Return Address)

方法开始执行后,只有 2 种方式可以退出 :方法返回指令,异常退出。

帧数据区(Stack Data)

你可能感兴趣的:(JVM,jvm)