深入理解Java虚拟机06--虚拟机字节码执行引擎

一.前言

物理机的执行引擎是直接在物理硬件如CPU、操作系统、指令集上运行的,但是对于虚拟机来讲,他的执行引擎由自己实现。 执行引擎有统一的外观(Java虚拟机规范),不同类型的虚拟机都遵循了这一规范,输入字节码文件,解析字节码处理,然后输出结果。

二.运行时栈帧结构

1、栈帧概念
栈帧(Stack Frame)用于支持方法调用和执行的数据结构,包含了局部变量表、操作数栈、动态连接和方法返回地址。

  • 局部变量表大小(max_locals),栈帧深度在编译时已经确定,并写入到了Code属性中;
  • 执行引擎运行的所有字节码指令都只针对当前栈进行操作;

2、局部变量表
局部变量表存储了方法参数以及方法内定义的局部变量。

  • Slot(变量槽):局部变量表容量最小单位,可以存放32位以内的数据类型;
  • refrence:
    • 直接或者间接找到到该对象在“堆内存”中数据存放的起始地址索引;
    • 直接或者间接找到对象所属数据类型在方法区中存储的类型信息;
  • 局部变量表建立在线程的堆栈上,所以操作两个连续的slot是否为原子操作,都不会引起数据安全问题,但是如果是64位的话,不允许任何方式单独访问其中的一个;
  • this:实例方法(非static)默认第一个(第0位索引)slot为当前对象自己的引用;
  • slot重用:
    • 当前字节码的pc计数器超出某个变量的作用域,那这个变量的slot可以交给别的变量使用;
    • 影响到正常的Java垃圾回收机制;
  • 赋null:因为上述slot重用的原因,当方法域内前面有局部变量定义了大内存实际不再使用的变量,紧接着后面的代码又是一个耗时的操作,这个时候及时赋null就显得有大的意义。因为一旦触发后,这部分的slot就可以被重用了。看起来就像是方法区内部进行“类gc"操作一样。但是,并不是任何时候都要进行赋null.以恰当的变量作用域来控制变量回收时间才是最优雅的方式,并且赋null值操作在经过JIT编译优化后会被消除掉,这样的话实际是没有任何意义的。
  • 初始值:和类变量不同,局部变量系统不会自动赋初始值,所以没有赋值是无法使用的,编译都无法通过。即使通过,字节码校验阶段也会检查出来而导致类加载失败;

3、操作数栈(Operand Stack)

  • 操作栈,后入先出;
  • 最大深度:Code属性表中的max_stacks;
  • 32位数据类型所占栈容量为1,64位所占容量为2;
  • 栈元素的数据类型必须和栈指令保持一致
  • 两个栈帧之间可以存在一部分的重叠,共享数据,这样在方法调用的时候避免的额外的参数复制。
  • Java虚拟机的解释执行引擎也是:基于栈的执行引擎;

4、动态连接(Dynamic Linking)
字节码中的方法的调用都是通过常量池中指定方法的符号作为参数

  • 静态解析:这种符号有的是类加载阶段或者首次使用初始化的时候转化为直接的引用
  • 动态连接:另外一部分是在运行时转化为直接引用

5、方法返回地址

  • 退出:
    • 正常退出:遇到返回的字节码指令;
    • 异常退出:本方法异常表中没有匹配的异常;
  • 退出后,恢复上层方法的局部变量表和操作栈,有返回值就把返回值压入上层调用者的栈中;

三.方法调用

定义:确定被调用方法的版本
1、解析

  • 编译器可知,运行期不可变。这类方法的调用成为解析,在类加载阶段进行解析。
  • 静态方法、私有方法、实例构造器方法、父类方法,符合上述条件。特点是:
    • 只能被invokestatic和invokespecial指令调用
    • 不可继承或者重写,编译时已经确定了一个版本。
    • 在类加载时会把符合引用解析为该方法的直接引用。
    • 非虚方法(注意final也是非虚方法,其他的都是虚方法)

2、静态分派

  • 概念:根据静态类型来定位方法的执行版本
  • 典型代表:方法的重载(方法名相同,参数类型不同)
  • 发生时间:编译阶段

3、动态分派

  • 概念:调用invokevirtual时,把常量池中的类方法符号解析到了不同的直接引用上。
  • 典型代表:重写,多态的重要体现
  • 过程:
    • 执行invokevitual指令
    • 在虚方法表(类加载阶段,类变量初始化结束后会初始化虚方法表)中查找方法,没有向上的父类进行查找
  • 方法宗量:方法的接收者与方法参数的总称
  • 单分派和多分派:
    • 只有一个宗量作为方法的选择依据,称为单分派。多个,则称为多分派。
    • 当前的Java是静态多分派、动态单分派的语言;

猜你喜欢

转载自www.cnblogs.com/ganchuanpu/p/9429450.html