JVM
-Java
虚拟机栈再学习
-
位于
RAM
,栈指针向下移动,则分配内存,向上移动,则释放内存。 -
当运行某段方法或程序时,虚拟机栈必须知道被存放在栈内所有数据的大小和生命周期。以便按照上述的分配存储方法通过上下移动指针来动态调整内存空间,这也是为什么程序内部数量庞大的
Java
对象一般不被存放在栈上的原因了。 -
速度快、每个线程数据共享(逃逸分析,优化程序)
-
只能存储一些基本数据类型的变量:
int、short、long、double、byte、float、double、boolea、char
、对象引用还有逃逸分析后的一些数据。 -
线程私有,和
Java
线程同一时间创建。 -
栈帧(由3大部分组成)
-
操作数栈.
- 被组织为一个数字数组,但是是通过push(进栈)和pop(出栈)来使用的。
- 先进后出、后进先出。
- 在编译为
Class
文件是,操作数栈的最大深度也被存储在方法的Code
属性的max_stacks
中。(最大深度不超过max_stacks中设定的最大值) - 操作数栈中的元素类型必须与字节码指令中的严格匹配,例如加法,一个int与一个float的情况。
- 在编译为
-
帧数据区
- 解析常量池中的数据。
- 方法执行完,恢复调用方法现场。
- 方法执行过程中抛出异常表,这里有一个异常表,当异常出现时查找异常表来看是否有catch语句,如果没有就终止这个方法的调用。
-
栈帧(细分)
-
局部变量表
- 局部变量区的子集
-
操作数栈
-
栈帧信息
- 静态解析
- 动态链接
- 方法返回地址
- 恢复调用现场
- 附加信息
-
方法调用
- 一切方法调用在
Class
文件里存储的都是符号引用,而不是实际运行时的内存布局。
- 一切方法调用在
-
解析(在类装载解析阶段就会把涉及的符号引用全部转换为确定的直接引用)
-
一切方法调用在
Class
文件里存储的都是符号引用,在类加载解析阶段,会将一部分符号引用转化为直接引用。 -
final 修饰的方法也是非虚方法的一种,无法被覆盖,版本唯一。
-
-
分派(案例)
- 静态单分派
- 静态多分派
- 动态单分派
- 动态多分派
-
评论区