深入理解Java虚拟机:Jvm总结-虚拟机字节码执行引擎

news2025/1/11 23:02:30

第八章 虚拟机字节码执行引擎

8.1 意义

不受物理条件制约地定制指令集与执行引擎的结构体系,能够执行那些不被硬件直接支持的指令集格式。输入的是字节码二进制流,处理过程是字节码解析执行的等效过程,输出的是执行结果

8.2 运行时栈帧结构

  • 栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息
    在这里插入图片描述

以Java程序的角度来看,同一时刻、同一条线程里面,在调用堆栈的所有方法都同时处于执行状态。而对于执行引擎来讲在活动线程中,只有位于栈顶的方法才是在运行的,只有位于栈顶的栈帧才是生效的,其被称为“当前栈帧”(Current Stack Frame),与这个栈帧所关联的方法被称为“当前方法”(Current Method)

  • 编译Java程序源码的时候,栈帧中需要多大的局部变量表,需要多深的操作数栈就已经被分析计算出来,也就是一个栈帧需要分配多少内存,并不会受到程序运行期变量数据的影响,而仅仅取决于程序源码和具体的虚拟机实现的栈内存布局形式

8.2.1 局部变量表

  • 存放方法参数和方法内部定义的局部变量,编译时就确定了该方法局部变量表的最大容量。
  • 变量槽(Slot)为最小单位,一个变量槽可以存放一个32位以内的数据类型,对于64位的数据类型,Java虚拟机会以高位对齐的方式为其分配两个连续的变量槽空间。Java语言中明确的64位的数据类型只有long和double两种
  • Java虚拟机通过索引定位的方式使用局部变量表,索引值的范围是从0开始至局部变量表最大的变量槽数量。
  • 当一个方法被调用时,Java虚拟机会使用局部变量表来完成参数值到参数变量列表的传递过程,即实参到形参的传递。如果执行的是实例方法, 表中第0位索引,默认是记录方法所属对象实例的引用。
  • 变量槽可以重用,但是可能会影响垃圾收集
  • 局部变量不初始化不能使用

8.2.2 操作数栈

  • 当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的,在方法的执行过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈和入栈操作。顾名思义,就是用来操作的。

  • 操作数栈中元素的数据类型必须与字节码指令的序列严格匹配,也就是说用于整型值的操作,不能使用其他的值。

  • 栈帧可以一部分重叠,可以共用一部分数据

8.2.3 动态连接

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,符号引用一部分会在类加载阶段或者第一次使用的时候就被转化为直接引用,这种转化被称为静态解析。另外一部分将在每一次运行期间都转化为直接引用,这部分就称为动态连接

8.2.4 方法返回地址

当一个方法开始执行后,只有两种方式退出这个方法:

  • 第一种方式是执行引擎遇到任意一个方法返回的字节码指令,这时候可能会有返回值传递给上层的方法调用者
  • 另外一种退出方式是在方法执行的过程中遇到了异常

一般来说,方法正常退出时,主调方法的PC计数器的值就可以作为返回地址,而方法异常退出时,返回地址是要通过异常处理器表来确定的。

8.3 方法调用

方法调用阶段唯一的任务就是确定调用哪个方法,不涉及方法内部细节

8.3.1 解析

解析是指当一个方法被调用时,JVM 如何确定实际要执行的方法。这里的解析调用具体为:方法的调用版本在编译期间就完全确定,在类加载的解析阶段就会把涉及的符号引用全部转变为明确的直接引用,在运行期是不可改变的方法。

主要有静态方法和私有方法两类,适合在类加载阶段进行解析

有五种调用方法的字节码指令:

  • invokestatic 用于调用静态方法
  • invokespecial 用于调用实例构造器()方法、私有方法和父类中的方法
  • invokevirtual用于调用所有的虚方法
  • invokeinterface用于调用接口方法,会在运行时再确定一个实现该接口的对象
  • invokedynamic先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法,由用户制定逻辑,前4种固定在虚拟机内部

只要能被invokestatic和invokespecial指令调用的方法,都可以在解析阶段中确定唯一的调用版本,Java语言里符合这个条件的方法共有静态方法、私有方法、实例构造器、父类方法4种,再加上被final修饰的方法(尽管它使用invokevirtual指令调用),这5种方法调用会在类加载的时候就可以把符号引用解析为该方法的直接引用。这些方法统称为“非虚方法”(Non-Virtual Method),与之相反,其他方法就被称为“虚方法”(Virtual Method)。

8.3.2 分派

分派调用是一种方法调用形式,可以是静态的也可是动态的。分派具有动态性,可以揭示多态的特性,比如重写和重载,根据实际代码更好理解

  1. 静态分派
    • 所有依赖静态类型来决定方法执行版本的分派动作,都称为静态分派。静态分派的最典型应用表
      现就是方法重载。静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机来执行
      的。
    • 虚拟机(或者准确地说是编译器)在重载时是通过参数的静态类型而不是实际类型作为
      判定依据的。由于静态类型在编译期可知,所以在编译阶段,Javac编译器就根据参数的静态类型决定
      了会使用哪个重载版本
    • 需要注意Javac编译器虽然能确定出方法的重载版本,但在很多情况下这个重载版本并不是“唯
      一”的,往往只能确定一个“相对更合适的”版本
  2. 动态分派
    • 在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。也就是方法重写的本质
    • 根源在于虚方法调用指令invokevirtual的执行逻辑:
      1. 找到操作数栈顶的第一个元素所指向的对象的实际类型,记作C
      2. 如果在类型C中找到与常量中的描述符和简单名称都相符的方法,则进行访问权限校验,如果通过则返回这个方法的直接引用,查找过程结束;不通过则返回java.lang.IllegalAccessError异常。
      3. 否则,按照继承关系从下往上依次对C的各个父类进行第二步的搜索和验证过程
      4. 如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常
    • 在Java里面只有虚方法存在,字段永远不可能是虚的,换句话说,字段永远不参与多态。当子类声明了与父类同名的字段时,虽然在子类的内存中两个字段都会存在,但是子类的字段会遮蔽父类的同名字段
  3. 单分派与多分派
    • 方法的接收者与方法的参数统称为方法的宗量,单分派是根据一个宗量对目标方法进行选择,多分派则是根据多于一个宗量对目标方法进行选择。
  4. 虚拟机动态分派的实现
    • 动态分派的方法版本选择过程需要运行时在接收者类型的方法元数据中搜索合适的目标方法
    • 一种优化方法是为类型在方法区中建立一个虚方法表,使用虚方法表索引来代替元数据查找以提高性能
    • 虚方法表中存放着各个方法的实际入口地址。如果某个方法在子类中没有被重写,那子类的虚方法表中的地址入口和父类相同方法的地址入口是一致的,都指向父类的实现入口。如果子类中重写了这个方法,子类虚方法表中的地址也会被替换为指向子类实现版本的入口地址。
    • 虚方法表一般在类加载的连接阶段进行初始化,准备了类的变量初始值后,虚拟机会把该类的虚方法表也一同初始化完毕。
    • 除此之外,还会使用类型继承关系分析(Class Hierarchy Analysis,CHA)、守护内联(Guarded Inlining)、内联缓存(InlineCache)等多种非稳定的激进优化来争取更大的性能空间

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

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

相关文章

jupyter出错ImportError: cannot import name ‘np_utils‘ from ‘keras.utils‘ ,怎么解决?

文章前言 此篇文章主要是记录一下我遇到的问题以及我是如何解决的,希望下次遇到类似问题可以很快解决。此外,也希望能帮助到大家。 遇到的问题 出错:ImportError: cannot import name np_utils from keras.utils ,如图&#xf…

Metasploit Pro 4.22.3-2024081901 (Linux, Windows) - 专业渗透测试框架

Metasploit Pro 4.22.3-2024081901 (Linux, Windows) - 专业渗透测试框架 Rapid7 Penetration testing, release Aug 19, 2024 请访问原文链接:https://sysin.org/blog/metasploit-pro-4/,查看最新版。原创作品,转载请保留出处。 作者主页…

SonicWall SSL VPN曝出高危漏洞,可能导致防火墙崩溃

近日,有黑客利用 SonicWall SonicOS 防火墙设备中的一个关键安全漏洞入侵受害者的网络。 这个不当访问控制漏洞被追踪为 CVE-2024-40766,影响到第 5 代、第 6 代和第 7 代防火墙。SonicWall于8月22日对其进行了修补,并警告称其只影响防火墙的…

代码随想录27期|Python|Day51|​动态规划|​115.不同的子序列|​583. 两个字符串的删除操作​|72. 编辑距离

115. 不同的子序列 本题是在原来匹配子序列的基础上增加了统计所匹配的子序列个数,也就是dp数组的定义和更新公式和原来的有所区别。 1、dp数组的定义 dp[i][j]表示以i-1和j-1为末尾的字符串中,给定字符串s包含目标字符串t的个数。注意这里不是长度。…

vs2019成功连接数据库mysql

②在vs2019中创建新项目,注意x64 ③ 右击项目打开属性 ④添加include路径 ⑤添加lib路径 点击确定后点击应用 ⑥ 点击全部确定 ⑦ ⑧启动mysql 进入数据库: 在数据库中创建student的表 ⑨在va2019中输入下面代码测试 注意:密码换成自己…

大数据Flink(一百一十六):Flink SQL的时间属性

文章目录 Flink SQL的时间属性 一、Flink 三种时间属性简介 二、Flink 三种时间属性的应用场景 三、​​​​​​​SQL 指定时间属性的两种方式 四、​​​​​​​​​​​​​​SQL 处理时间DDL定义 五、​​​​​​​​​​​​​​SQL 事件时间DDL定义 Flink SQL的时…

Nature子刊|C4平台助力单细胞多组学分析,揭秘睾丸生殖细胞瘤的分子特征

在精准医疗的大潮中,单细胞多组学技术正成为研究肿瘤微环境的强有力工具。最近,一项发表在《Nature Communications》的重磅研究,就利用了包括DNBelab C Series在内的平台设备,对睾丸生殖细胞瘤(Seminoma)进…

矩阵分析 学习笔记3 多项式矩阵 jordan标准型

就是说这个矩阵里面的各个元素都是多项式,多项式的主角是类目大(自变量)。 多项式矩阵的秩是啥呢? 0多项式就是完全0的那种,就一个0,类目大都没有了。 多项式矩阵的秩和带一个类目大进去变成普通矩阵的秩不…

最大间距问题

LeetCode164 最大间距 基数排序 #include <iostream> #include <vector> using namespace std;class Solution { public:int maximumGap(vector<int>& nums) {int nnums.size();if(n<2) return 0;int exp1;int Maxnums[0];vector<int> buf(n)…

WD mybook10T硬盘exfat变0字节恢复方法

WD的mybook系列应该全部是3.5寸台式机机械硬盘然后加了盒子做成了移动存储&#xff0c;单盘容量已经极高了&#xff0c;此类盘出厂的文件系统一般为exfat&#xff08;可能是厂商为了方便mac客户使用&#xff09;。下边这个案例就是我们经常遇到的exfat变0字节。 故障存储:WD m…

用网卡的ap模式抓嵌入式设备的网络包

嵌入式设备不像pc上&#xff0c;有一些专门的工具比如wareshark来抓包&#xff0c;嵌入式设备中&#xff0c;有的可能集成了tcpdump&#xff0c;可以用来进行简单的抓包&#xff0c;但是不方便分析&#xff0c;况且有的嵌入式设备不一定就集成了tcpdump工具。 关于tcpdump工具…

[001-03-007].第07节:Redis中的事务

我的后端学习大纲 我的Redis学习大纲 1、Redis事务是什么&#xff1a; 1.可以一次执行多个命令&#xff0c;本质是一组命令的集合。一个事务中的所有命令都会序列化&#xff0c; 按顺序地串行化执行而不会被其他命令插入&#xff0c;不许加塞2.一个队列中&#xff0c;一次性、…

AI+RPA机器人 实现自动调用 kimi 的 AI 对话功能(内附使用教程)

前言 今天尝试写一个用RPA自动调用kimi的AI对话功能。 把这个写好之后&#xff0c;就是后面其他一切AI相关的基础&#xff0c;比如自动用AI写文章啊&#xff0c;比如搭建一个微信AI机器人啊等等&#xff0c; 都能用到今天实现的AI对话功能。 话不多说&#xff0c;直接看思路…

在 Windows 中使用系统文件检查器

DiSM.exe /Online /Cleanup-image /Restorehealth

项目管理方法,方法和框架–初学者指南

项目管理方法&#xff0c;方法和框架–初学者指南 项目可以通过各种方式成功结束。但是&#xff0c;最好&#xff0c;最受欢迎的项目管理方法&#xff0c;方法和框架总是在变化。新概念无时无刻不在出现。所有成功的项目都包含一整套方法&#xff0c;工具和技术。实际上&#x…

基于SpringBoot+Vue+MySQL的考研互助交流平台

系统展示 用户前台界面 管理员后台界面 系统背景 本文设计并实现了一个基于SpringBoot、Vue.js和MySQL的考研互助交流平台。该平台旨在为广大考研学子提供一个集资源共享、学习交流、经验分享、心理辅导等功能于一体的综合性在线社区。通过SpringBoot构建高效稳定的后端服务&am…

Whistle 客户端抓包工具

Whistle 客户端 安装或更新 官网&#xff1a; 关于whistle GitBook (wproxy.org)https://wproxy.org/whistle/ Whistle 客户端目前只支持 Mac 和 Windows 系统&#xff0c;如果需要在 Linux、 Docker、服务端等其它环境使用&#xff0c;可以用命令行版本&#xff1a;GitHub…

汽车免拆诊断案例 | 沃尔沃V40 1.9TD断续工作

故障现象 一辆04款的沃尔沃V40 1.9 TD&#xff0c;发动机代码D4192T3&#xff0c;使用博世EDC15C发动机管理。客户说车子断续工作&#xff0c;怀疑是正时皮带出现问题。卸下上皮带盖&#xff0c;检查发现皮带仍然在原来的位置上并且没有出现松动。起动发动机&#xff0c;车辆能…

1 MATLAB 绘图函数函数: plot

>> t -10:0.001:10; >> x sin(t); >> plot(t,x)

python中,在.之后出现的提示中这些带圈的C代表什么意思?其前面的绿色红箭头和红色标记又代表什么意思?

python中&#xff0c;在.之后出现的提示中这些带圈的C代表什么意思&#xff1f;其前面的绿色红箭头和红色标记又代表什么意思&#xff1f; 在Python中&#xff0c;带圈的"C"通常表示"类"。这意味着在该提示中&#xff0c;你正在与一个类的属性或方法进行交…