原创 | jvm02、java虚拟机栈

小白带你快速了解!

java虚拟机栈是jvm内存结构中的一员,也就是我们平常所说的栈内存,它是线程私有的,每个线程都有属于自己的一个java虚拟机栈,java虚拟机栈的生命周期和线程相同,也就是说当一个线程开始了,也就产生了一个java虚拟机栈。

既然是栈,肯定有个什么玩意入栈和出栈,java虚拟机栈主要是用来存放线程运行方法时所需的数据,指令和方法返回地址等,那么靠什么存储?这就需要栈帧,这么个意思

原创 | jvm02、java虚拟机栈_第1张图片

当你一个线程开始了,你就必须给我来个java虚拟机栈,我要存储数据啊,靠什么存储?栈帧啊,存储什么数据呢?运行方法所需的数据啊,所以栈帧的产生必须是一个方法被调用了,也就是说,线程开始,有了一个java虚拟机栈,当一个方法被调用,就产生一个栈帧用来存放运行这个方法所需的一些数据,一个方法从被调用到结束就对应一个栈帧从入栈到出栈的过程,可以得知,栈帧是和方法息息相关的。这个栈帧包含这么些东西。

  1. 局部变量表
  2. 操作数栈
  3. 动态链接
  4. 方法返回地址

如果你想深入了解请继续往下看!

庆哥陪你深入分析!

以上小白为大家介绍了什么是java虚拟机栈,我这里总结一下

  1. java虚拟机栈线程私有,随线程开始而产生。
  2. java虚拟机栈主要靠方法被调用的时候产生的栈帧来存放数据。
  3. 栈帧随一个方法被调用而产生
  4. 一个方法从被调用到结束就对应栈帧在java虚拟机栈中入栈和出栈的过程。

我们之前常说,基本数据类型是保存在栈内存中的,现在要知道的是这是根据时期而定的,因为如果你单单理解基本数据类型是存放在栈内存的时候,当你遇到运行时常量池的时候你一定会迷,为啥,运行时常量池也是存放基本数据类型啊,那到底谁存放呢?

这就要根据时期来说了。当你编写一个java文件,被编译成class文件之后,这个class文件中就产生了一个class文件常量池,当被加载到内存中的时候,这个class文件常量池就成了运行时常量池,当然,运行时常量池包含的东西要多点,这时候基本数据类型也是存放在这个运行时常量池的。

但是,你要注意了,这个时候并没有什么线程开始和方法调用,所以也就没有什么栈帧来存放数据,只有当你的方法被调用的时候,才会产生一个栈帧来存放数据,这时候就会存放基本数据类型的数据,而我猜想这些数据也是从运行时常量池拿来的。那么栈帧中是如何操作的呢?其实栈帧也分为这么几个部分

  1. 局部变量表
  2. 操作数栈
  3. 动态链接
  4. 方法返回地址

而我们说的基本类型存放在栈内存,更加准确的说就是存放在栈帧中的,这里有一张图

原创 | jvm02、java虚拟机栈_第2张图片

大家注意了,图中底色淡黄色的描述目前应该是错误的,这里我也有疑问就是,比如int a = 66这句代码是如何存储的,这个66是存放在局部变量还是这个a是存放在局部变量,我们之前也说,基本数据类型和对象引用是存放在栈内存的,那么比如String s = new String()中,s叫做对象引用,这个s是存放在哪里?在局部变量中吗?

以上是我不理解的地方,如果谁对这块比较熟悉,还请不耐烦的教我一下,这里我请教了@刘欣和@黄俊还有@小猴子三位前辈大佬,奈何我资质愚钝,还是不怎么理解,唉!辛苦三位前辈了。我私下会再做研究!

另外关于类变量和局部变量有这么一个区别,对基本数据类型来说,对于类变量(static)和全局变量,如果不显式地对其赋值而直接使用,则系统会为其赋予默认的零值,而对于局部变量来说,在使用前必须显式地为其赋值,否则编译时不通过。

这个栈帧中除了局部变量表之外还有操作数栈,动态链接和方法返回地址。那什么是操作数栈呢?在《深入理解java虚拟机》中有这么一段话“整数加法的字节码指令iadd在运行的时候操作数栈中最接近栈顶的两个元素已经存入了两个int型的数值,当执行这个指令时,会将这两个int值出栈并相加,然后将相加的结果入栈。”也就是说操作数栈也是存储数据的区域。

每一个栈帧中都会有这么一个引用,这个引用存放在运行时常量池中,这个引用指向该栈帧,这个引用的目的是为了支持方法调用过程中的动态链接。符号引用在类加载阶段或者第一次使用阶段会直接转换为直接引用,这个叫做静态解析,还有的是在每一次运行期间转化为直接引用,这部分就称为动态链接。

方法的退出也就意味着栈帧从java虚拟机栈中出栈,方法的退出一般有两种,一种是正常退出,一种是异常退出,但是,无论是以哪种方式退出,最终都要返回到方法调用的地方,如果是正常退出的话,那么这个返回地址就是调用者的程序计数器的值,如果是异常退出的话,返回地址是由异常处理器表决定的。

以上为大家浅显的介绍了java虚拟机栈的一些相关知识点,其中关于局部变量表那块自己也不是很明白,真的是想的脑壳疼!

今天就先到这,我的问题也在文中提出来了,如果你理解的比较透彻,可以教教我,万分感谢,我会继续研究,后续会继续分享!大家是如何理解的,欢迎留言啊!

脑壳疼。。。写这篇文章的时候也请教了不少人,在此一并感谢!

待续。。。

你可能感兴趣的:(原创,Java虚拟机)