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

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

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)等多种非稳定的激进优化来争取更大的性能空间

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一文读懂在线学习凸优化技术

一文读懂在线学习凸优化技术 在当今的数据驱动时代,机器学习算法已成为解决复杂问题的关键工具。在线学习凸优化作为机器学习中的一项核心技术,不仅在理论研究上具有重要意义,还在实际应用中展现出巨大的潜力。本文将深入浅出地介绍在线学习…

编程新纪元:AI如何成为你的编程伙伴

随着人工智能技术的不断进步,我们正步入一个编程的新纪元。在这个时代,AI不仅仅是一个工具,更是程序员的伙伴。它通过提供智能辅助、自动化编码和增强开发效率,正在改变我们编写和理解代码的方式。本文将探讨AI如何成为程序员的得…

精品PPT | 离散制造行业智能工厂总体解决方案

一、建设背景 离散制造业,包括机械制造业、汽车制造业和家电制造业等,其生产过程涉及多个不连续的工序,产品通常由多个零件装配而成。这类行业面临的挑战包括品种多、批量小、订单变化快、临时插单频繁以及外协件管理困难等问题,…

2025年第八届计算机图形和虚拟国际会议(ICCGV 2025)即将召开!

2025年第八届计算机图形和虚拟国际会议(ICCGV 2025)将于2025年2月21-23日在中国成都举行。随着信息技术的飞速发展,计算机图形学与虚拟现实技术正以前所未有的速度重塑着我们的认知世界与交互体验。从沉浸式游戏到精准医疗模拟,从…

如何将镜像推送到docker hub

前言 这一篇应该是最近最后一篇关于docker的博客了,咱来个有始有终,将最后一步——上传镜像给他写完,废话不多说,直接进入正题。 登录 首先需要确保登录才能推送到你的仓库中去,在终端输入docker login,输入用户名和…

AutosarMCAL开发——基于EB Gpt驱动

目录 1.Gpt原理2.EB配置以及接口应用2.1 EB配置2.2 接口应用 3.总结 1.Gpt原理 autosar GPT模块(General Purpose Timer,通用定时器)主要用于汽车ECU中的时间测量、计数和产生定时中断。它支持单次性和周期性定时器,可以在达到预…

阿里云机房火灾?盘点五大机房火灾现场

号主:老杨丨11年资深网络工程师,更多网工提升干货,请关注公众号:网络工程师俱乐部 下午好,我的网工朋友。 不知道大家有没有看到今天有关阿里云的新闻,没错就是阿里云新加坡的网络节点出现了异常&#xff…

【828华为云征文|如何使用华为云Flexus X实例搭建私人博客:从配置到发布全指南】

文章目录 华为云Flexus X实例介绍搭建专属私人博客准备工作具体操作指南服务器环境确认宝塔软件商店操作一键部署WordPress私人博客域名解析WordPress安装初始页数据库信息配置运行安装程序配置博客信息博客管理后台(默认为wp-login.php页面)博客前台页面…

让AI成为打光工具人(Stable Diffusion进阶篇:Imposing Consistent Light)

前言 正巧我之前一直在学习的B站up也恢复了关于Stable Diffusion的教程,今天就一起来学习一下IC-Light,这样一项可以帮助喜欢拍照的同学们打光布景的插件。 IC-Light IC-Light的全称是Imposing Consistent Light,翻译过来就是给物体施加一…

Git 修改Push后的Commit Message

向远程仓库push代码之后,在IDEA中无法直接修改Commit Message,需要在终端或控制台中输入以下命令(HEAD~1中的1表示只对最后一个提交进行修改,因此1可以自定义) git rebase -i HEAD~1执行完rebase指令后,会…

F12抓包06-4:导出metersphere脚本

课程大纲 metersphere是一站式的开源持续测试平台,我们可以将浏览器请求导出为HAR文件,导入到metersphere,生成接口测试。 metersphere有2种导入入口(方式),导入结果不同: 1.导入到“接口定义”…

白盒测试覆盖例题

答案:A D 知识点 定义 特点 语句覆盖 被测试程序中的每条语句至少测试一次 对执行逻辑覆盖很低,一般认为是很弱的逻辑覆盖 判定覆盖 被测试程序每个判定表达式至少落得一次“真”值和“假值” 判定覆盖比语句覆盖更强一些。判定可以是一个条件或…

DIC技术助力新能源汽车主机厂力学测试研发与整车性能提升

在新能源汽车研发过程中,非接触式全视场应变DIC测量方案,越来越受到汽车主机厂的信赖与认可。传统接触式传感器,在精度、灵活性和数据处理能力上存在局限。DIC技术可提供精确、高效、全视场、便捷的非接触式测量解决方案。 在汽车研发阶段&a…

Proteus 仿真设计:开启电子工程创新之门

摘要: 本文详细介绍了 Proteus 仿真软件在电子工程领域的广泛应用。从 Proteus 的功能特点、安装与使用方法入手,深入探讨了其在电路设计、单片机系统仿真、PCB 设计等方面的强大优势。通过具体的案例分析,展示了如何利用 Proteus 进行高效的…

Win10 9月更新补丁KB5043064发布:21H2/22H2用户不容错过!

系统之家于9月11日发出最新报道,微软向Win10用户推出9月最新更新补丁KB5043064,更新后,21H2用户更新后系统版本号将升至19044.4894,22H2用户更新后版本号也升至19045.4894。本次更新解决了部分内存泄露导致的问题。下面就和系统之…

哪些开放式耳机好?开放式耳机的优缺点有哪些?

现在的开放式耳机真的是非常的多了,品牌众多的情况下,我们很难的有效选择出一款开放式耳机到底适不适合自己,所以这篇文章就是来告诉大家如何才能更好的辨别一款适合自己并且还不错的开放式耳机,当然,会有人问&#xf…

Python 封装、继承和多态

在学习 Python 这门编程语言时,你会接触到一些重要的面向对象编程(OOP)概念,比如封装、继承和多态。这些概念不仅是 Python 的核心特性,也是理解和使用高级编程技巧的基础。本文将通俗易懂地解释这些概念,特…

302.AI学术论文搜索工具的智能体验

Hey朋友们, 你是否曾在学术的海洋里迷失方向,为了找到一篇论文而苦苦挣扎? 就像在茫茫大海中寻找灯塔,我们渴望一盏明灯,指引我们前行。 别担心,今天我来给你介绍一个超级给力的工具——302.AI学术论文…

9.9日记录

1.常见排序算法的复杂度 1.快速排序 1.1快速排序为什么快 从名称上就能看出,快速排序在效率方面应该具有一定的优势。尽管快速排序的平均时间复杂度与“归并排序”和“堆排序”相同,但通常快速排序的效率更高,主要有以下原因。 出现最差情况…

推荐一款开源、高效、灵活的Redis桌面管理工具:Tiny RDM!支持调试与分析功能!

1、引言 在大数据和云计算快速发展的今天,Redis作为一款高性能的内存键值存储系统,在数据缓存、实时计算、消息队列等领域发挥着重要作用。然而,随着Redis集群规模的扩大和复杂度的增加,如何高效地管理和运维Redis数据库成为了许…