JVM学习笔记——栈区

栈区 Stack Area

  栈是运行时的单位,堆是存储单位,栈解决程序的运行问题,即程序如何执行,如何处理数据。

  每个线程在创建时都创建一个该线程私有的虚拟机栈,每个栈里有许多栈帧,一个栈帧对应一个 Java 方法

 

栈的特点:

  • 每个栈与它所对应的线程生命周期保持一致

  • 栈主管 Java 程序运行,保存方法的局部变量,部分结果,参与方法的调用与返回

  • JVM 对栈的操作只有两种,方法执行入栈和执行结束出栈

  • 栈的访问快速有效,访问速度仅次于程序计数器

  • 对栈来说不存在垃圾回收问题

 

栈帧

  栈区中的一个栈对应一个线程,栈中的一个栈帧对应一个方法,在栈帧中封装了方法执行的局部变量表、操作数栈、返回地址、动态链接以及一些附加信息,如对程序调优调试信息等。

  在活动的线程中,只有当前正在执行的方法才是有效的,因此该方法对应的栈顶栈帧称为当前栈帧,该方法称为当前方法,定义该方法的类为当前类

  执行引擎所有的字节码指令只针对当前栈帧进行操作。

  如图所示,正在执行的线程所对应的当前线程中,栈帧1 对应的 方法1 调用了 栈帧2 对应的 方法2,方法2 又调用了 方法3,因此当前栈帧入栈。每个栈帧都存有所对应方法的各种信息。当正在执行的 方法3 执行完毕后,当前栈帧把执行结果返回给 栈帧2,当前栈帧出栈,栈帧2 变为当前栈帧,当 栈帧1 也出栈时,该线程执行完毕,执行其他线程。

 

局部变量表

  局部变量表也称为局部变量数组或本地变量表。

  局部变量表本质上是一个数字数组,主要用于存储方法参数和定义在方法内的局部变量

  • 局部变量表建立在线程私有的栈中,是线程私有数据,不存在安全问题

  • 局部变量表所需的容量大小,在编译器就确定下来,在方法运行期不会改变其大小

  • 方法嵌套调用的次数由栈的大小决定

  • 局部变量表的变量只在当前方法调用中有效,方法调用结束后,方法栈帧销毁,局部变量表随之销毁

 

操作数栈

  操作数栈也成为了表达式栈。

  操作数栈主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的储存空间。

  • 栈中的任何一个元素可以是任意的 Java 数据类型

  • 操作数栈只能通过标准的入栈出栈操作来完成数据访问,不支持索引

  • 如果被调用方法带有返回值,返回值会被压入当前栈帧的操作数栈中,并更新程序计数器的下一条指令

 

动态链接

  每个栈帧内部包含一个指向运行时常量池中该栈帧所属方法的引用,这个引用的目的就是为了支持当前方法的代码实现动态链接。

  动态链接的作用就是为了将符号引用转换为方法的直接引用,当一个方法调用其他方法时,就通过常量池中指向方法的符号引用完成。

 

方法返回地址

  当一个方法被执行后,有两种方式退出这个方法。

  正常完成出口:执行引擎遇到任意一个方法返回的字节码指令,产生返回值传递给上层的方法调用者。

  异常完成出口:在方法执行过程中遇到了异常,并且这个异常没有在方法体内得到处理,只要在本方法的异常表中没有搜索到匹配的异常处理器,就会导致方法退出。异常完成出口的方式退出,不会给它的调用者产生任何返回值。

  无论采用何种方式退出,在方法退出之前,都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在栈帧中保存一些信息,用来帮助恢复它的上层方法的执行状态。

posted @ 2021-10-07 00:15  乌池鱼  阅读(72)  评论(0)    收藏  举报