JVM虚拟机栈大集合

JVM虚拟机栈大集合

一个方法相当于一个栈帧,下面进行结构和过程解析:

栈帧包括结构:局部变量表,操作数栈,动态链表,返回地址,对象实例引用,变量槽.....

1.局部变量表

说白了就是存放方法内部定义的局部变量(8大基本数据类型),(String引用类型),(对象引用<reference类型>),(指向一条字节码指令地址<returnAddress类型>)

 

8大基本数据类型:int、short、byte、double、char、boolean、float、long

String引用类型:String是个final类和八大数据类型对应的引用类型是一样一样的。

对象引用<reference类型>:相当于给对象指定类型,告诉JVM中的GC回收对象的方式,这个实际开发中很少用到

 

注(重点):其实讲了这么多,可能对变量,常量,String引用类型,八大数据类型的封装类,常量池.....他们的存放位置在哪?

 

首先先区分变量和常量的区别

常量:常量代表程序运行过程中不能改变的值。也就是用final修饰

例如:final double PI = 3.14;

变量:变量是程序运行中,其值可以改变量

例如:double PI = 3.14;

 

定义在类中方法外:

1.成员变量(非静态的)(八大基础数据类型)和常量(非静态的)(final定义的八大基础数据类型)都在堆

 

2.成员变量(静态的)(八大基础数据类型)和常量(静态的)(final定义的八大基础数据类型)都在方法区,在jdk1.8的时候通过HotSpot技术移到了元空间,元空间在本地内存中。

 

3.String常量池在jdk1.8的时候通过HotSpot技术移到堆中。

 

4.String成员变量分配在堆,这个声明是在方法区,实际对象是在堆,中间只是个引用。

 

5.常用的八大引用类型,在范围内的分配在方法区内 范围外(New实例化)的分配在堆,范围外的声明是在方法区,实际对象是在堆,中间只是个引用。

 

6.new实例化存放在堆,声明是在方法区,实际对象是在堆。

 

定义在类中方法内:

1.局部变量(包括静态的)(八大基础数据类型)和局部定义常量(包括静态的)(final定义的八大基础数据类型)都是在栈中

 

2.String分配在堆,声明是在栈,实际对象是在堆,中间只是个引用。

 

3.常用的八大引用类型看数据范围,因为有自动拆装箱,在范围内的分配在栈 范围外(New实例化)的分配在堆,声明是在栈,实际对象是在堆,中间只是个引用。

 

4.new实例化存放在堆,声明是在栈,实际对象是在堆,中间只是个引用。

JVM虚拟机栈大集合

所以这里就涉及到地址和值的问题,也就是==和equals的区别。

 

2.动态链接

指在字节码文件中,常量池指向调用方法的引用,意思也就是,在方法中调用方法,给被调用的方法一个标识,告诉你们这是个方法,和其他的信息区别开。

JVM虚拟机栈大集合

3.返回地址

这个说白了,就是程序要退出这个方法了,要告诉栈帧,我要退出去了,回到被调用的位置,你要帮我保存一下方法执行中处理的信息,异常退出就不用保存了,然后程序计数器指向下一条指令开始执行。在我们平时Debug就知道,当一个方法调用完毕后,最后会回到调用的位置,也就是入口位置。

 

3.操作数栈

HotSpot提出了栈顶缓存技术,目的是为了减少频繁使用入栈和出栈的指令,减少了IO的开销

运行过程:

 

JVM虚拟机栈大集合

JVM虚拟机栈大集合

JVM虚拟机栈大集合

JVM虚拟机栈大集合

JVM虚拟机栈大集合

1.这里的操作数栈仅仅只是作为一个缓存

2.变量赋值,首先数值入栈,然后再出栈找到对应局部变量表里面的下标

3.任何需要进行计算的数据都是先入栈再出栈进行计算后,结果再入栈,然后再出栈找到对应局部变量表里面的下标。