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

目录

一、栈帧

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: ()Iflags: ACC_PUBLICCode:stack=2, locals=4, args_size=10: bipush        1002: istore_13: bipush        1005: istore_26: bipush        1008: istore_39: iload_110: iload_211: iadd12: iload_313: imul14: ireturnLineNumberTable:line 29: 0line 30: 3line 31: 6line 32: 9LocalVariableTable:Start  Length  Slot  Name   Signature0      15     0  this   Lcom/cmmon/instance/classLoad/NotInitialization;3      12     1     a   I6       9     2     b   I9       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.mzph.cn/news/38686.shtml

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

相关文章

【环境配置】Windows10终端和VSCode下能够直接打开Anaconda-Prompt

很多小伙伴在 Windows 下做深度学习开发的时候&#xff0c;遇到终端没有在 Linux 那么方便&#xff0c;那么我们现在就可以来设置一下&#xff1b;这样我们也可以在文件夹内部右键打开终端&#xff0c;也可以在 VS Code 里面新建一个虚拟环境的控制台&#xff1b;这里主要是针对…

佛祖保佑,永不宕机,永无bug

当我们的程序编译通过&#xff0c;能预防的bug也都预防了&#xff0c;其它的就只能交给天意了。当然请求佛祖的保佑也是必不可少的。 下面是一些常用的保佑图&#xff1a; 佛祖保佑图 ——————————————————————————————————————————…

【c语言】动态内存管理(超详细)

他治愈了身边所有人&#xff0c;唯独没有治愈他自己—超脱 csdn上的朋友你们好呀&#xff01;&#xff01;今天给大家分享的是动态内存管理 &#x1f440;为什么存在动态内存分配 我们定义的局部变量在栈区创建 int n 4;//在栈上开辟4个字节大小int arr[10] { 0 };//在栈上开…

Android Socket使用TCP协议实现手机投屏

本节主要通过实战来了解Socket在TCP/IP协议中充当的是一个什么角色&#xff0c;有什么作用。通过Socket使用TCP协议实现局域网内手机A充当服务端&#xff0c;手机B充当客户端&#xff0c;手机B连接手机A&#xff0c;手机A获取屏幕数据转化为Bitmap&#xff0c;通过Socket传递个…

Excel设置某列或者某行不某行不可以编辑,只读属性

设置单元格只读的三种方式: 1、通过单元格只读按钮&#xff0c;设置为只为 设置行或者列的只读属性&#xff0c;可以设置整行或者整列只读 2、设置单元格编辑控件为标签控件(标签控件不可编辑) 3、通过锁定行&#xff0c;锁定行的修改。锁定的行与只读行的区别在于锁定的行不…

openGauss学习笔记-40 openGauss 高级数据管理-锁

文章目录 openGauss学习笔记-40 openGauss 高级数据管理-锁40.1 语法格式40.2 参数说明40.3 示例 openGauss学习笔记-40 openGauss 高级数据管理-锁 如果需要保持数据库数据的一致性&#xff0c;可以使用LOCK TABLE来阻止其他用户修改表。 例如&#xff0c;一个应用需要保证表…

GPT垂直领域相关模型 现有的开源领域大模型

对于ToC端来说&#xff0c;广大群众的口味已经被ChatGPT给养叼了&#xff0c;市场基本上被ChatGPT吃的干干净净。虽然国内大厂在紧追不舍&#xff0c;但目前绝大多数都还在实行内测机制&#xff0c;大概率是不会广泛开放的&#xff08;毕竟&#xff0c;各大厂还是主盯ToB、ToG市…

视频集中存储安防监控平台EasyCVR优化AI硬件接入时的通道显示异常问题

安防视频监控平台视频集中存储EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。 安防监控视频云存储平台EasyCVR既具…

使用Logstash将数据从MySQL同步至Elasticsearch(有坑)

文章目录 一、准备工作1、安装elasticSearchkibana2、安装MySQL3、安装Logstash 二、全量同步1、准备MySQL数据与表2、上传mysql-connector-java.jar3、启动Logstash4、修改logstash.conf文件5、修改full_jdbc.sql文件6、打开Kibana创建索引和映射7、重启logstash进行全量同步8…

TCP/IP协议追层分析物理层(第三十九课)

TCP/IP协议追层分析物理层(第三十九课) 1 物理层:建立、维护、断开物理连接,定义了接口及介质,实现了比特流的传输。 1、传输介质分类 有线介质:网线(双绞线)、光纤 无线介质:无线电 微波 激光 红外线 2、双绞线分类: 五类cat5: 适用于100Mbps 超五类cat5e:适用于…

Qt扫盲- Graphics View框架理论综述

Graphics View框架理论综述 一、概述二、Graphics View 体系结构1. The Scene2. The View3. 图元 Item 三、图形视图坐标系统1. 图元Item的坐标2. Scene Scene坐标3. View 视图坐标4. 坐标映射 四、关键特性1. 缩放和旋转2. 打印3. 拖放4. 鼠标指针和 提示5. 动画6. OpenGL渲染…

【100天精通python】Day35:一文掌握GUI界面编程基本操作

目录 专栏导读 1 GUI 编程概述 1.1 为什么需要GUI&#xff1f; 1.2 常见的GUI编程工具和库 1.3 GUI应用程序的组成和架构 2 使用Tkinter 库 进行GUI编程 2.1 使用Tkinter库进行GUI编程的基本流程 2.2 使用Tkinter库进行GUI编程 2.2.1 导入Tkinter库 2.2.2 添加标签和…

绘制世界地图or中国地图

写在前面 在8月初,自己需要使用中国地图的图形,自己就此也查询相关的教程,自己也做一下小小总结,希望对自己和同学们有所帮助。 最终图形 这个系列从2022年开始,一直更新使用R语言分析数据及绘制精美图形。小杜的生信笔记主要分享小杜学习日常!如果,你对此感兴趣可以加…

MySQL存储结构及索引

文章目录 MySQL结构1.2存储引擎介绍1.3存储引擎特点InnoDB逻辑存储结构 MyISAMMemory区别及特点存储引擎选择 索引索引概述索引结构BTreeHash索引分类聚集索引&二级索引索引语法SQL性能分析索引优化最左前缀法则范围查询字符串不加引号模糊查询or连接条件数据分布影响覆盖索…

达梦数据库dbms_stats包的操作实践记录

索引的统计信息收集 GATHER_INDEX_STATSindex_stats_show 根据模式名&#xff0c;索引名获得该索引的统计信息。用于经过 GATHER_TABLE_STATS、GATHER_INDEX_STATS 或 GATHER_SCHEMA_STATS 收集之后展示。返回两个结果集&#xff1a;一个是索引的统计信息&#xff1b;另一个是…

Kotlin优点及为什么使用Kotlin

文章目录 一 Hello Kotlin二 Kotlin优点三 团队为什么采用 Kotlin 一 Hello Kotlin Kotlin和Andriod 二 Kotlin优点 三 团队为什么采用 Kotlin

Mendix 基础审计模块介绍

一、前言 作为售前顾问&#xff0c;帮助客户选型低代码产品是日常工作。考察一家低代码产品的好坏&#xff0c;其中一个维度就是产品的成熟度。产品成熟度直接影响产品在使用中的稳定性和用户体验&#xff0c;对于新工具导入和可持续运用至关重要。 那怎么考察一个产品是否成…

【校招VIP】java语言考点之ConcurrentHashMap1.7和1.8

考点介绍&#xff1a; ConcurrentHashMap是JAVA校招面试的热门考点&#xff0c;主要集中在1.7和1.8的底层结构和相关的性能提高。 理解这个考点要从map本身的并发问题出发&#xff0c;再到hashTable的低性能并发安全&#xff0c;引申到ConcurrentHashMap的分块处理。同时要理解…

【C++】做一个飞机空战小游戏(八)——生成敌方炮弹(rand()和srand()函数应用)

[导读]本系列博文内容链接如下&#xff1a; 【C】做一个飞机空战小游戏(一)——使用getch()函数获得键盘码值 【C】做一个飞机空战小游戏(二)——利用getch()函数实现键盘控制单个字符移动【C】做一个飞机空战小游戏(三)——getch()函数控制任意造型飞机图标移动 【C】做一个飞…

SpringBoot中的可扩展接口

目录 # 背景 # 可扩展的接口启动调用顺序图 # ApplicationContextInitializer # BeanDefinitionRegistryPostProcessor # BeanFactoryPostProcessor # InstantiationAwareBeanPostProcessor # SmartInstantiationAwareBeanPostProcessor # BeanFactoryAware # Applicati…