目录
栈帧和局部变量表
概述
栈帧概述
栈帧概念结构
局部变量表
slot是复用的实例
操作数栈
概述
动态连接
方法调用
静态分派和动态分派
-
栈帧和局部变量表
-
概述
- JVM的字节码执行引擎,功能基本就是输入字节码文件,然后对字节码进行解析并处理,最后输出执行的结果
- 实现方式可能有通过解释器直接解释执行字节码
- 或者是通过即时编译器产生本地代码,也就是编译执行,当然也可能两者皆有
-
栈帧概述
- 栈帧是用于支持JVM进行方法调用和方法执行的数据结构
- 栈帧随着方法调用而创建,随着方法结束而销毁
- 栈帧里面存储了方法的局部变量、操作数栈、动态连接、方法返回地址等信息
-
栈帧概念结构
-
局部变量表
- 用来存放方法参数和方法内部定义的局部变量的存储空间
- (1)以变量槽slot为单位,目前一个slot存放32位以内的数据类型
- (2)对于64位的数据占2个slot
- (3)对于实例方法,第0位slot存放的是this,然后从1到n,依次分配给参数列表
- (4)然后根据方法体内部定义的变量顺序和作用域来分配slot
- (5)slot是复用的,以节省栈帧的空间,这种设计可能会影响到系统的垃圾收集行为
-
slot是复用的实例
- 看空间变化的区别(多了个变量空间居然变多了)
- 没加a变量时,这样分配slot
- 这是因为slot里还在用bs,所以没回收
- 加a变量时,bs是个局部变量,出了块就不再用了
- slot会复用,分配会发生变化
- bs就能进行回收了,可用空间自然就变大了
- 再加个bs2,明显bs2没有进行回收
- 这是因为bs2并没有被复用覆盖掉
- 只有bs被覆盖了
- 所以可以再加个占用空间小的变量,把bs2复用覆盖掉,让它能进行回收
- 也可以赋值为null,把指针弄没,也能进行回收
-
操作数栈
-
概述
- 用来存放方法运行期间,各个指令操作的数据
- (1)操作数栈中元素的数据类型必须和字节码指令的顺序严格匹配
- (2)虚拟机在实现栈帧的时候可能会做一些优化,让两个栈帧出现部分重叠区域,以存放公用的数据
-
动态连接
- 每个栈帧持有一个指向运行时常量池中该栈帧所属方法的引用,以支持方法调用过程的动态连移
- (1)静态解析:类加载的时候,符号引用就转化成直接引用
- (2)动态连接:运行期间转换为直接引用
-
方法调用
- 就是确定具体调用哪一个方法,并不涉及方法内部的执行过程
- (1)部分方法是直接在类加载的解析阶段,就确定了直接引用关系
- (2)但是对于实例方法,也称虚方法,因为重载和多态,需要运行期动态委派
-
静态分派和动态分派
- 分派:又分成静态分派和动态分派
- (1)静态分派:所有依赖静态类型来定位方法执行版本的分派方式,比如:重载方法
- (2)动态分派:根据运行期的实际类型来定位方法执行版本的分派方式,比如:覆盖方法
- 单分派和多分派:
- 就是按照分派思考的纬度,多余一个的就算多分派,只有一个的称为单分派
- 如何执行方法中的字节码指令:JVM通过基于栈的字节码解释执行引擎来执行指令,JVM的指令集也是基于栈的