小白日更第三十天->JVM之栈帧

本文详细介绍了Java虚拟机栈中的栈帧结构及其作用。栈帧在执行Java方法时创建,存储局部变量表、操作数栈、动态连接和方法返回信息。每个方法调用对应一个栈帧,压栈和弹栈伴随着方法的调用与结束。局部变量表存放各种数据类型和对象引用,操作数栈用于计算和存储临时结果。动态连接负责符号引用到直接引用的转换。此外,文章还提及了线程和Native方法在JVM中的角色。
摘要由CSDN通过智能技术生成

关于栈

我觉得还是老规矩百度百科~
在这里插入图片描述
相信小伙伴都对栈不陌生,百度百科也已经解释的很清楚了,我也没必要废话了是不是
在这里插入图片描述

栈帧

当我们运行一个java方法的时候JVM就会在java虚拟机栈中创建一个栈帧,为什么这里强调是java方法,因为jvm中不仅有java虚拟机栈还有本地方法栈,那这个是用来干什么的呢,小伙伴们直到jvm是建立在操作系统之上的,无法直接和操作系统进行相关的操作,比如线程,学过java的小伙伴都知道Thread,并且直到new一个线程后,调用start()方法就可以启动线程了,但是线程是操作系统的概念,所以也就是说我们无法通过java直接操作线程,但是c++可以呀,我们看一下start方法的源码就一目了然了在这里插入图片描述
然后我们看看这个
start0()方法
在这里插入图片描述
可以看到这个方法是用
Native
修饰的,简单地讲,一个Native Method就是一个java调用非java代码的接口。至此我们也就明白了,java确实不能创建线程,操作系统可以创建线程,而且我们可以利用c++的代码或者其他语言的代码和操作系统进行交互。上面的判断操作,就是当一个线程启动的时候,它的状态(threadStatus)会被设置为0(即线程为NEW状态)。

好像说了些不该说的,本来想说栈帧的怎么聊到了线程,那我们回归主题
我了解到的栈帧就是java在执行方法的时候会在栈中创建一个栈帧,也就是说一个栈中可以有多个栈帧,因为我们总不能就执行一个方法吧。栈帧会随着方法的调用而创建,随着方法的结束而消亡。这个栈帧中存储着这个方法中的变量,其实原则上各个栈帧之间的数据是不能共享的,但是在方法间调用时,jvm会将一方法的返回值赋值给调用它的栈帧中。每一个方法调用,就是一个压栈的过程,每个方法的结束就是一个弹栈的过程。小伙伴们可以想一下递归调用的过程,我们在方法中不断的调用自身,一个方法被调用就会压入栈,执行完就会弹出栈,那执行的结果是不是应该返回给调用者。压栈的时候都将会将当前的栈帧置于栈顶,每个栈不会同时操作多个栈帧,只会操作栈顶,当栈顶操作结束时,会将该栈帧弹出,同时会释放该栈帧内存,其下一个栈帧将变为栈顶

栈帧的组成

局部变量表
局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、 byte、 char、 short、 int、float、 long、 double) 、 对象引用(reference类型, 它并不等同于对象本身, 可能是一个指向对象起始地址的引用指针, 也可能是指向一个代表对象的句柄或者其他与此对象相关的位置) 和returnAddress类型(指向了一条字节码指令的地址) 。
这些数据类型在局部变量表中的存储空间以局部变量槽(Slot) 来表示, 其中64位长度的longdouble类型的数据会占用两个变量槽, 其余的数据类型只占用一个。 局部变量表所需的内存空间在编译期间完成分配, 当进入一个方法时, 这个方法需要在栈帧中分配多大的局部变量空间是完全确定的, 在方法运行期间不会改变局部变量表的大小。小伙伴们注意一下, 这里说的**“大小”**是指变量槽的数量,虚拟机真正使用多大的内存空间(譬如按照1个变量槽占用32个比特、 64个比特, 或者更多) 来实现一个变量槽, 这是完全由具体的虚拟机实现自行决定的事情。

操作数栈
可以理解操作数栈为一个存放临时计算结果的,同时作为计算过程中变量临时的存储空间。当一个方法刚开始执行的时候,一个新的栈帧也会被创建,这个方法的操作数栈是空的。如果被调用的方法带有返回值的话,其返回值将会被压入当前栈帧的操作数栈中。
动态连接
在一个class文件中,一个方法要调用其他方法,需要将这些方法的符号引用转化为其在内存地址中的直接引用,而符号引用存在于方法区中的运行时常量池。Java虚拟机栈中,每个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用,持有这个引用的目的是为了支持方法调用过程中的动态连接(Dynamic Linking)。这些符号引用一部分会在类加载阶段或者第一次使用时就直接转化为直接引用,这类转化称为静态解析。另一部分将在每次运行期间转化为直接引用,这类转化称为动态连接。
方法返回
我们执行一个方法的时候,肯定是要退出的。那退出的方式就有两种,一是正常退出,而是程序异常导致退出,无论方法采用何种方式退出,在方法退出后都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在当前栈帧中保存一些信息,用来帮他恢复它的上层方法执行状态。

以上就是我对栈帧的理解,有什么不对的地方希望小伙伴们在评论区积极留言在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值