HotSpot虚拟机之字节码执行引擎

news2025/3/16 6:18:31

目录

一、栈帧

1. 栈帧结构

2. 基于栈的解释执行过程

二、方法调用

1. 方法调用指令

2. 分派

三、动态类型语言

四、参考资料


一、栈帧

1. 栈帧结构

        栈帧是Java虚拟机栈进行方法调用和执行的数据结构,是方法最基本的执行单元,是栈的元素。一个栈帧分配多大内存,则不受运行期影响,由程序源码和占内存布局决定(内存大小编译期可知)。每一个方法的调用开始和结束,都对应JVM栈的元素(栈帧)的入栈和出栈。

        处于Java虚拟机栈顶的栈帧,称为“当前栈帧”;当前栈帧所关联的方法,称为“当前方法”。从Java程序层面看,同一时刻、同一线程里,栈的所有方法都处于执行状态;从执行引擎层面看,只有处于栈顶的方法才是执行状态。

        栈帧的结构包含:局部变量表、操作数栈、动态连接、返回地址、附加信息,如下表所示。注意:方法调用时,用局部变量表完成参数值到参数变量列表的传递过程,即:实参到形参的传递

栈帧结构

作用

特点

局部变量表

(Local Variables Table)

变量值的存储空间

1.存储:方法参数及方法定义的局部变量

2.局部变量表容量以变量槽(slot)为最小单位;

3.方法Code属性max_locals决定最大容量(slot数量)

4.每个slot都能存储boolean、byte、char、short、int、float、returnAddress类型的数据;

5.64位JVM时,只有long、double会以高位对齐的方式分配两个连续的slot空间

6.实例方法时,第0位slot是this参数;其他:方法参数、方法局部变量的顺序

7.slot被回收重用的根本原因:slot中是否还存有对象的引用或值

操作数栈

(Operand Stack)

操作数据的栈

1.JVM解释执行引擎称为“基于栈的操作引擎”;

2.栈的最大深度由编译器Code属性的max_stacks决定

3.字节码指令往栈中写入和读取操作数,即:操作数的入栈和出栈;

4.栈中元素数据类型与字节码指令的类型必须严格匹配

5.模型中JVM栈的元素(栈帧)是相互独立的,但是JVM实际优化时,可能会有重叠区域。

动态连接

(Dynamic Linking)

栈帧所属方法的引用

1.每个栈帧都包含一个指向常量池该栈帧所属方法的引用(反过来,字节码的方法调用以常量池的符号引用作为参数)

2.静态解析:编译器符号引用转直接引用;

  动态连接:每次运行时符号引用转直接引用。

返回地址

(Return Address)

返回给方法调用者

1.两种方式退出当前方法:

  “正常调用完成”:执行引擎遇到方法的返回指令;

  “异常调用完成”:当前方法的异常表中没有搜索到匹配的异常,则异常退出(不会有任何返回值)

2.方法正常退出时,一般主调方法的PC计数值可作为返回地址,若有返回值则压入主调方法的栈帧中

附加信息

其他信息

如调试、性能收集相关的信息

        其中,reference数据类型的作用:                                                                                    

  • 根据直接引用或间接引用查找到堆中实例对象的起始地址或索引;   
  • 根据直接引用或间接引用查找到元空间(方法区)的类型信息(反射机制获取Class信息); 

2. 基于栈的解释执行过程

        指令集架构分类如下,Java是基于栈的指令集架构

  • 基于栈的指令集架构:字节码指令流大部分都是零地址指令,依赖操作数栈工作,其优点:可移植;   
  • 基于寄存器的指令集架构:依赖于寄存器来访问和存储数据,如:主流PC机(x86二地址指令集)

        执行字节码有两种选择(或两着兼备):解释执行(解释器)、编译执行(即时编译产生本地机器代码),下面是基于栈的解释执行过程实例、源码和class文件如下。指令含义参考《HotSpot虚拟机之Class文件及字节码指令》。

public int calc() {
    int a = 100;
    int b = 100;
    int c = 100;
    return (a + b) * c;
}
  public int calc();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: bipush        100
         2: istore_1
         3: bipush        100
         5: istore_2
         6: bipush        100
         8: istore_3
         9: iload_1
        10: iload_2
        11: iadd
        12: iload_3
        13: imul
        14: ireturn
      LineNumberTable:
        line 29: 0
        line 30: 3
        line 31: 6
        line 32: 9
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      15     0  this   Lcom/cmmon/instance/classLoad/NotInitialization;
            3      12     1     a   I
            6       9     2     b   I
            9       6     3     c   I

二、方法调用

1. 方法调用指令

        方法调用阶段唯一目的是确定被调用方法的版本,即:调用哪个方法,其指令有5种:invokestatic、invokespecial、invokevirtual、invokeinterface、invokedynamic,如下表所示。

方法调用指令

特点

invokestatic

作用:调用静态方法;

invokespecial

作用:调用实例构造器<init>()方法、私有方法、父类中的方法

invokevirtual

1.作用:调用所有的虚方法;

2.该指令:动态分派实现方法复写

invokeinterface

作用:调用接口方法,运行时确定一个实现该接口的方法

invokedynamic

1.作用:动态调用方法;

2.运行时动态解析动态解析调用点限定符所引用的方法,再去执行;

注意:

   a.invokestatic、invokespecial、invokevirtual、invokeinterface其分派逻辑固化在JVM内部;而invokedynamic分派逻辑由用户设定的引导方法来决定

   b.只要能被invokestatic、invokespecial调用的方法,在编译器可以确定方法版本,如:静态、实例构造器<init>()、私有、父类、final修饰的方法;

   c.final修饰的方法虽然用invokevirtual调用,但它是非虚方法。

        invokevirtual指令不仅把常量池的方法符号引用解析为直接引用,同时根据方法接收者的实际类型来选择方法版本。invokevirtual指令解析过程,如下步骤:

  • step1:找到操作数栈顶元素指向的对象的实际类型C;
  • step2:类型C中查找与当前常量池匹配的方法时,且访问权限校验,通过则返回该方法,查找结束;否则抛出异常:java.lang.IllegalAccessError;
  • step3:否则,从下往上的继承关系对C的父类,进行搜索和验证;
  • step4:否则,没有查找到匹配的方法,抛出异常:java.lang.AbstractMethodError。

2. 分派

        分派揭示Java多态性的实现,即:如重载、重写是如何实现。其分类:静态分派、动态分派或是单分派、多分派,如下表所示。

分派分类

概念

应用

特点

静态分派

所有依赖静态类型来决定方法版本的分派动作

方法重载

1.静态分派发生在编译期

2.重载版本多个时,选择最合适的顺序:自动类型转换、自动装箱、装箱实现接口、父类(从下往上)、可变参数方法

动态分派

运行期根据实际类型来决定方法版本的分派动作

方法重写

1.动态分派发生在运行期

2.由invokevirtual指令实现。

注意:

   a.只有方法有多态,而字段永远不参与多态;

   b.变量的“静态类型”和“实际类型”:(都可能变化,但是变化时期不同)

      静态类型:变化在使用时发生,且变量本身的类型不会改变,且最终在编译期可知;

      实际类型:变化结果在运行期确定,编译期不知道一个对象的实际类型是什么

   c.类型“宽化转换”:chart > int > long > float > double(不会匹配byte、short类型);

   d.“方法的宗量”:方法接收者、方法的参数

       分派:根据一个宗量对目标方法进行选择;

       分派:根据多于一个宗量对目标方法进行选择。

        注意:方法重写的本质是不仅把常量池的方法符号引用解析为直接引用,同时根据方法接收者的实际类型来选择方法版本;字段不参与多态,但子类声明与父类的相同的字段时,子类内存中两个字段都会存在,但子类会遮蔽父类的同名字段

        方法重写实现多态,在运行时频繁从元数据进行查找,解决该问题的方法:invokevirtual的虚方法表;invokeinterface的接口方法表。虚方法表目的是存储该类各个方法的实际入口地址,如下所示其特点。

三、动态类型语言

        JDK7增加了动态类型指令invokedynamic,其类型检查的主过程在运行期,而不是编译期

四、参考资料

HotSpot虚拟机之Class文件及字节码指令_爱我所爱0505的博客-CSDN博客

HotSpot虚拟机之类加载过程及类加载器_爱我所爱0505的博客-CSDN博客

百度安全验证

【Java 虚拟机原理】栈帧 | 动态链接 | 方法区 | 字节码文件二进制分析-腾讯云开发者社区-腾讯云

Java虚拟机运行时栈帧结构_java栈帧_爱躺平的咸鱼的博客-CSDN博客

【Java -- 虚拟器】方法分派模型 -- 静态分派、动态分派_51CTO博客_java虚拟器

Java中的静态分派和动态分派原理_51CTO博客_静态分派

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/883423.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

文件操作 和 IO

目录 ​编辑一、认识文件 1、文件路径 2、其它知识 二、Java 中操作文件 三、文件内容的读写 1、Reader 2、InputStream 3、输出 一、认识文件 文件是在硬盘上存储数据的一种方式&#xff0c;操作系统帮我们把硬盘的一些细节都封装起来了 我们只需要了解文件相关的一些…

stack+queue

适配器 介绍 在C的标准模板库&#xff08;STL&#xff09;中&#xff0c;有几种适配器&#xff0c;它们是一些容器或函数对象的包装&#xff0c;提供了不同的接口和功能&#xff0c;用于适应特定的需求 分类 STL中的适配器可以分为两类&#xff1a;容器适配器和迭代器适配器 容…

PHP自己的框架实现function引入和dump函数(完善篇一)

1、实现效果 2、创建三个function.php 3、文件加载&#xff08;KJ.php&#xff09; 定义目录 define("FILE_PATH",KJ_CORE./file); //定义框架文件路径define("COMMON_PATH",ROOT_PATH./common); //定义公共目录 加载文件 public static function run(){…

一种多策略下RabbitMQ的延时队列实现

1.为什么会用到延时队列? 场景: 最近在开发一款系统中遇到这样一个场景,A系统开通套餐需要把套餐信息以邮件的形式发送给相关工作人员,经过人工审核通过后,在B系统里面开通,A系统会调B系统套餐列表接口查询套餐是否开通成功,开通成功则从A系统去完成订单,假如超过设定时间未开…

vue 发现页面找不到3秒后跳转到本页面

这个路由跳转用到的是编程式跳转this.$router.push 两种写法&#xff1a; 第一种可以通过path来跳转 goto(/find) find是路由里边的路径 <span click"goto(/find)">发现音乐</span> <span click"goto(/my)">我的音乐</span> <…

Virtualbox设置访问外网以及主机和虚拟机互通

参考链接 1、设置使虚拟机访问外网。选中虚拟机&#xff0c;右击选择“设置”。 2、在设置中选择“网络”&#xff0c;然后点击“网卡1”&#xff0c;选择“网络地址转换&#xff08;NAT&#xff09;”模式&#xff0c;点击“确定”。 4.此时你的虚拟机就可以访问外网了 5…

NRF24L01+数据手册_关于几种工作模式

使用的是官方数据手册的章节编号&#xff0c;原文截图方便对照&#xff0c;部分翻译&#xff08;标蓝&#xff09;、个人理解&#xff08;标紫&#xff09;&#xff0c;关键信息&#xff08;标红&#xff09;。 6.1 Operational Modes操作模式 6.1.1 State diagram状态机图 6…

sqlloader学习笔记

INFILE的用法 1&#xff09;模糊导入多个数据的文件。 可以在文件名中使用通配符。 星号 &#xff08;*&#xff09; 表示复数字符&#xff0c;问号 &#xff08;&#xff1f;&#xff09; 表示单个字符。 INFILE emp*.dat INFILE m?emp.dat 2&#xff09;如果不需要导入数据…

麒麟arm架构 编译安装qt5.14.2

1、先在官网下载qt源码&#xff1a; https://download.qt.io/archive/qt/5.14/5.14.2/single/[qt源码下载地址] 2、解压编译 使用tar -xvf qt-everywhere-src-5.14.2.tar.xz 解压压缩包 cd qt-everywhere-src-5.14.2 执行 ./configure --prefix/usr/local/qt.5.14.2 make -…

【Nginx17】Nginx学习:目录索引、字符集与浏览器判断模块

Nginx学习&#xff1a;目录索引、字符集与浏览器判断模块 今天要学习的内容有几个还是大家比较常见的&#xff0c;所以学习起来也不会特别费劲。对于目录的默认页设置大家都不会陌生&#xff0c;字符集的设置也比较常见&#xff0c;而浏览器的判断这一块&#xff0c;可能有同学…

大模型基础:GPT家族与提示学习

大模型基础:GPT 家族与提示学习 从 GPT-1 到 GPT-3.5 GPT(Generative Pre-trained Transformer)是 Google 于2018年提出的一种基于 Transformer 的预训练语言模型。它标志着自然语言处理领域从 RNN 时代进入 Transformer 时代。GPT 的发展历史和技术特点如下: GPT-12018年6月…

OpenSSH 远程升级到 9.4p1

OpenSSH 远程升级到 9.4p1 文章目录 OpenSSH 远程升级到 9.4p1背景升级前提1. 升级 OpenSSL2. 安装并启用Telnet 升级OpenSSH 背景 最近的护网行动&#xff0c;被查出来了好几个关于OpenSSH 的漏洞。这是因为服务器系统安装后&#xff0c;直接使用了系统自带版本的OpenSSH &am…

lib调试报LNK2038 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”

最近用cef&#xff0c;要debug调试&#xff0c;引用库时&#xff0c;提示&#xff1a; LNK2038 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2” 研究后的结论&#xff1a;这是因为&#xff0c;这个库的实现方式太老&#xff1a; #if _HAS_ITERATOR_DEBUG…

【C++笔记】C++之类与对象(上)

【C笔记】C之类与对象&#xff08;上&#xff09; 1、类是结构体的升级2、类中可以定义的东西3、类访问限定符4、类的声明5、类的实例化(定义)6、类的大小的计算7、this指针 1、类是结构体的升级 C的一个显著特征就是兼容C语言&#xff0c;所以C把结构体“升级”成了“类”&am…

高等数学 | 微分方程解决单中值问题、高阶导数的莱布尼兹公式

单中值问题都可以用通过求解微分方程的特解构造辅助函数&#xff0c;再用罗尔定理即可。 高阶导数的莱布尼兹公式推导以及应用&#xff0c;先求导至能够发现某次求导开始为0的时候&#xff0c;对其使用莱布尼兹公式。

Photoshop制作漂亮光泽感3D按钮

原文链接(https://img-blog.csdnimg.cn/45472c07f29944458570b59fe1f9a0e0.png)

简单记录牛客top101算法题(初级题C语言实现)BM24 二叉树的中序遍历 BM28 二叉树的最大深度 BM29 二叉树中和为某一值的路径

1. BM24 二叉树的中序/后续遍历 要求&#xff1a;给定一个二叉树的根节点root&#xff0c;返回它的中序遍历结果。                          输入&#xff1a;{1,2,#,#,3} 返回值&#xff1a;[2,3,1]1.1 自己的整体思路&#xff08;与二叉树的前序遍…

HCIP——BGP协议

目录 一.什么是BGP&#xff1f; 二.IGP和EGP 三.BGP的特点 四.BGP的数据包 五.BGP的工作过程 BGP的六种状态机 六.BGP的路由黑洞问题 七.BGP的防环机制——水平分割 八.BGP的宣告问题 九.BGP的自动汇总 十.BGP的安全特性 十一.BGP的选路规则 一.什么是BGP&#xff1f; 1.…

ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440)

安全之安全(security)博客目录导读 ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440) 二、CVE-2018-19440 一、ATF(TF-A)安全通告 TFV-8 (CVE-2018-19440) Title 不保存x0~x3寄存器可能会将信息从一个非安全世界的SMC client泄漏到另一个 CVE ID …

学习ts(二)数据类型(接口和对象类型、数组类型)

interface 重名会重合到一起 如果两个interface名称相同&#xff0c;会把两个合到一起 重复定义同一个需要类型相同 不能多或者减少属性 设置任意key 当定义接口返回数据时&#xff0c;我们不确定接口会返回多少&#xff0c;知道所需要的固定属性&#xff0c;其余属性可以…