https://www.yuque.com/u21195183/jvm/ar6bqp#60990303
Java虚拟机
1、Java虚拟机栈帧
Java虚拟机栈(Java Virtual Machine Stack),早期也叫Java栈,其内部保存着一个一个栈帧(Stack Frame),对应着一次一次的Java方法调用,为线程私有
- 栈帧的内部结构:
- 局部变量表
- 操作数栈(表达式栈)
- 动态链接(指向运行时常量池的方法引用)
- 方法返回地址(方法正常退出或者异常退出的定义)
- 一些附加信息
a、局部变量表
也称之为局部变量数组或本地变量表
定义为一个数字数组,主要用于存储方法参数和定义在方法体内部的局部变量,这些数据类型包括基本数据类型、对象引用、returnAdress类型
局部变量表建立在线程的栈上,线程的私有数据
所需要的容量大小在编译期间就确定了
关于Slot的理解
局部变量表中最基本的存储单元就是Slot
变量的分类:
按照数据类型分类:
1、基本数据类型
2、引用数据类型
按照在类中声明的位置分类:
1、成员变量(在使用前都经历过默认初始化赋值):类变量、实例变量
类变量:linking
的prepare
阶段给类变量默认赋值—>initial
阶段给类变量显式赋值即静态代码块赋值
实例变量:随着对象的创建会在堆空间中分配实例变量空间,并进行默认赋值
2、局部变量
在使用前必须要进行显式赋值
补充说明:
在栈帧中,与性能调优关系最为密切的部分就是局部变量表,方法执行时虚拟机使用局部变量表完成方法的传递
局部变量表中的变量也是重要的垃圾回收根节点
b、操作数栈
主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间
当一个方法执行的时候,一个新的栈帧也会随之创建出来,这个方法的操作数栈是空的
操作数栈虽然是数组,但是不能通过访问索引的方式来进行数据访问
如果被调用方法带有返回值的话,返回值也会压入当前栈帧的操作数栈中
c、动态链接
常量池:Constant Pool
在Java源文件被编译到字节码文件中时,所有的变量和方法引用都作为符号引用(Symbolic Reference)保存在文件的常量池里
例如:描述一个方法引用另一个方法时就是通过常量池中指向的方法的符号引用来表示的
那么动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用
- 静态链接
- 动态链接
方法的绑定机制:
- 早期绑定(编译期间可以确定)
- 晚期绑定
虚方法和非虚方法
子类对的多态性的使用前提:类的继承关系、方法的重写
虚拟机提供了几条方法调用指令:
- invokestatic
- invokespecial
- invokevirtual
- invokeinterface
2、Java虚拟机生命周期
生命周期与线程一致
3、Java虚拟机的作用
保存局部变量、部分结果,并参与方法的调用与返回
局部变量 VS 成员变量
基本数据变量 VS 引用类型变量(类、数组、接口)
4、Java虚拟机的特点
(1)快速有效的分配存储方式
(2)JVM对Java栈的操作只有两个
每个方法执行,伴随着进栈(入栈、压栈)
执行结束后的出栈工作
(3)对于栈来说不存在垃圾回收的问题
GC、OOM
5、栈中可能出现的问题
StackOverflowError、OutOfMemoryError