深入理解java虚拟机精华总结:运行时栈帧结构、方法调用、字节码解释执行引擎

深入理解java虚拟机精华总结:运行时栈帧结构、方法调用、字节码解释执行引擎

  • 运行时栈帧结构
    • 局部变量表
    • 操作数栈
    • 动态连接
    • 方法返回地址
  • 方法调用
    • 解析
    • 分派
      • 静态分派
      • 动态分派
  • 基于栈的字节码解释执行引擎

运行时栈帧结构

Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame) 则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素,栈帧存储了方法的局部变量表操作数栈动态连接方法返回地址等信息。

在这里插入图片描述

局部变量表

局部变量表(Local Variables Table)是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量。局部变量表的容量以变量槽(Variable Slot)为最小单位,每个变量槽都应该能存放一个boolean、byte、char、short、int、float、reference或returnAddress类型的数据。

在这里插入图片描述

操作数栈

操作数栈(Operand Stack)也常被称为操作栈,它是一个后入先出(Last In First Out,LIFO)栈

当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的,在方法的执行过程中,会有各种字节码指令往操作数栈中写入和提取内容,也就是出栈和入栈操作。譬如在做算术运算的时候是通过将运算涉及的操作数栈压入栈顶后调用运算指令来进行的,又譬如在调用其他方法的时候是通过操作数栈来进行方法参数的传递。

在这里插入图片描述

动态连接

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接(Dynamic Linking)。Class文件的常量池中存有大量的符号引用,字节码中的方法调用指令就以常量池里指向方法的符号引用作为参数。这些符号引用一部分会在类加载阶段或者第一次使用的时候就被转化为直接引用,这种转化被称为静态解析。另外一部分将在每一次运行期间都转化为直接引用,这部分就称为动态连接

在这里插入图片描述

方法返回地址

当一个方法开始执行后,只有两种方式退出这个方法。第一种方式是执行引擎遇到任意一个方法返回的字节码指令(正常调用完成);另外一种退出方式是在方法执行的过程中遇到了异常,并且这个异常没有在方法体内得到妥善处理(异常调用完成)。

在方法退出之后,必须返回到最初方法被调用时的位置。方法正常退出时,主调方法的PC计数器的值就可以作为返回地址,栈帧中很可能会保存这个计数器值。而方法异常退出时,返回地址是要通过异常处理器表来确定的,栈帧中就一般不会保存这部分信息。

退出时可能执行的操作:恢复上层方法的局部变量表和操作数栈,把返回值(如果有的话)压入调用者栈帧的操作数栈中,调整PC计数器的值以指向方法调用指令后面的一条指令等。

在这里插入图片描述

方法调用

方法调用并不等同于方法中的代码被执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法),暂时还未涉及方法内部的具体运行过程。Class文件的编译过程中不包含传统程序语言编译的连接步骤,一切方法调用在Class文件里面存储的都只是符号引用,而不是方法在实际运行时内存布局中的入口地址(也就是之前说的直接引用)。

在这里插入图片描述

解析

所有方法调用的目标方法在Class文件里面都是一个常量池中的符号引用,在类加载的解析阶段,会将其中的一部分符号引用转化为直接引用,这种解析能够成立的前提是:方法在程序真正运行之前就有一个可确定的调用版本,并且这个方法的调用版本在运行期是不可改变的。这类方法的调用被称为解析(Resolution)。

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

在这里插入图片描述

分派

在这里插入图片描述

静态分派

所有依赖静态类型(在编译期可知)来决定方法执行版本的分派动作,都称为静态分派。静态分派的最典型应用表现就是方法重载(Overload)。静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机来执行的。

在这里插入图片描述

动态分派

动态分派的实现过程与 重写(Override) 有着很密切的关联。

正是因为invokevirtual指令执行的第一步就是在运行期确定接收者的实际类型,所以invokevirtual指令并不是把常量池中方法的符号引用解析到直接引用上就结束了,还会根据方法接收者的实际类型来选择方法版本,这个过程就是Java语言中方法重写的本质。我们把这种在运行期根据实际类型确定方法执行版本的分派过程称为动态分派。

在这里插入图片描述

基于栈的字节码解释执行引擎

一段简单的算术代码。

public int calc() {
	int a = 100;
	int b = 200;
	int c = 300;
	return (a + b) * c;
}

使用javap命令看看它的字节码指令。

public int calc();
	Code:
		Stack=2, Locals=4, Args_size=1
		 0: bipush 100
		 2: istore_1
		 3: sipush 200
		 6: istore_2
		 7: sipush 300
		10: istore_3
		11: iload_1
		12: iload_2
		13: iadd
		14: iload_3
		15: imul
		16: ireturn
}

在这里插入图片描述

首先,执行偏移地址为0的指令,Bipush指令的作用是将单字节的整型常量值(-128~127)推入操作数栈顶,跟随有一个参数,指明推送的常量值,这里是100。

在这里插入图片描述

执行偏移地址为2的指令,istore_1指令的作用是将操作数栈顶的整型值出栈并存放到第1个局部变量槽中。后续4条指令(直到偏移为11的指令为止)都是做一样的事情,也就是在对应代码中把变量a、b、c赋值为100、200、300。

在这里插入图片描述

执行偏移地址为11的指令,iload_1指令的作用是将局部变量表第1个变量槽中的整型值复制到操作数栈顶。

在这里插入图片描述

执行偏移地址为12的指令,iload_2指令的执行过程与iload_1类似,把第2个变量槽的整型值入栈。

在这里插入图片描述

执行偏移地址为13的指令,iadd指令的作用是将操作数栈中头两个栈顶元素出栈,做整型加法,然后把结果重新入栈。在iadd指令执行完毕后,栈中原有的100和200被出栈,它们的和300被重新入栈。

在这里插入图片描述
执行偏移地址为14的指令,iload_3指令把存放在第3个局部变量槽中的300入栈到操作数栈中。这时操作数栈为两个整数300。下一条指令imul是将操作数栈中头两个栈顶元素出栈,做整型乘法,然后把结果重新入栈,与iadd完全类似。

在这里插入图片描述

执行偏移地址为16的指令,ireturn指令是方法返回指令之一,它将结束方法执行并将操作数栈顶的整型值返回给该方法的调用者。到此为止,这段方法执行结束。

上面的执行过程仅仅是一种概念模型,虚拟机最终会对执行过程做出一系列优化来提高性能,实际的运作过程并不会完全符合概念模型的描述。更确切地说,实际情况会和上面描述的概念模型差距非常大,差距产生的根本原因是虚拟机中解析器和即时编译器都会对输入的字节码进行优化,即使解释器中也不是按照字节码指令去逐条执行的。

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

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

相关文章

Vue3 自定义指令让元素自适应高度,el-table在可视区域内滚起来

我始终坚持,前端开发不能满足于实现功能,而是需要提供优秀的交互与用户体验。即使没有产品没有UI的小项目,也可以自己控制出品质量,做到小而美。所以前端们不仅仅需要了解框架如何用,还要学习一些设计、交互、体验的知…

诗圣杜甫不同时期的代表作

杜甫一生大致分为四个时期。 中青年时期 青年时,作为官三代的杜甫并不缺钱,四处游历,与李白、高适唱和、仙游,成为佳话。这个时期杜甫的作品热血豪迈,气势蓬勃。代表作首推《望岳》: 岱宗夫如何&#xf…

2023/5/8总结

JAVA基础知识(2) 1.方法 1、方法定义 格式:public static void 方法名(){ //方法体 } 2、方法调用 格式:方法名(); 3、方法的通用格式 public static 返回值类型方法名&…

C++面向对象(黑马程序员)

内存分区模型 #include<iostream> using namespace std;//栈区数据注意事项&#xff1a;不要返回局部变量的地址 //栈区的数据由编译器管理开辟和释放int* func(int b) //形参数据也会放在栈区 {b 100;int a 10; //局部变量存放在栈区&#xff0c;栈区的数据在函数执…

存bean和取bean

准备工作存bean获取bean三种方式 准备工作 bean:一个对象在多个地方使用。 spring和spring boot&#xff1a;spring和spring boot项目&#xff1b;spring相当于老版本 spring boot本质还是spring项目&#xff1b;为了方便spring项目的搭建&#xff1b;操作起来更加简单 spring…

vue+express+mysql做一个简单前后端交互,从数据库中读取数据渲染到页面

1.下载上次的包 npm I &#xff0c;同时下载新的包 axios 2.打开数据库服务器&#xff0c;同时使用新建数据库一样&#xff0c;数据包名 3.新建一个项目 4.全局注册axios 5.新建一个server文件夹&#xff08;里面在建一个index.js的主文件&#xff09;用来放我们后端写的东西 …

数据结构与算法基础(王卓)(36):交换排序之快排【第三阶段:深挖解决问题】精华!精华!精华!!!重要的事情说三遍

目录 Review&#xff1a; 具体问题&#xff1a; 操作核心&#xff1a; 注&#xff1a; 操作分解&#xff1a; 操作实现&#xff1a; 问题&#xff08;1&#xff09;&#xff1a;进行不一样次数的 if / else 判断 问题&#xff08;2&#xff09;&#xff1a;通过判断条件…

TypeScript 最近各版本主要特性总结

&#xff08;在人生的道路上&#xff0c;当你的期望一个个落空的时候&#xff0c;你也要坚定&#xff0c;要沉着。——朗费罗&#xff09; TypeScript 官网 在线运行TypeScript代码 第三方中文博客 特性 typescript是javascript的超集&#xff0c;向javascript继承额外的编辑…

2023鲁大师评测沟通会:鲁大师尊享版登场、“鲁小车”正式上线

作为硬件评测界的“老兵”&#xff0c;鲁大师不仅有着十几年的硬件评测经验&#xff0c;并且一直都在不断地尝试、不断地推陈出新。在5月9日举行的“2023年鲁大师评测沟通会”上&#xff0c;鲁大师向大众展示了在过去一年间取得的成果。 PC业务迭代升级&#xff0c;鲁大师客户端…

干货满满!破解FP安全收款难题

怎样安全收款是做擦边产品卖家比较忧虑的问题&#xff0c;2023年已经即将来到了年中&#xff0c;跨境卖家们在这一方面做得怎么样了呢&#xff1f; 这期分享破解FP独立站收款难题的方法。 一、商家破解FP收款难题方法 1.第三方信用通道 优点&#xff1a;信用卡在国外使用率比…

好家伙,又一份牛逼笔记面世了...

最近网传的一些裁员的消息&#xff0c;搞的人心惶惶。已经拿到大厂offer的码友来问我&#xff1a;大厂还能去&#xff0c;去了会不会被裁。 还在学习的网友来问我&#xff1a;现在还要冲互联网么&#xff1f; 我是认为大家不用恐慌吧&#xff0c;该看啥看啥&#xff0c;该学啥…

ASEMI代理ADI亚德诺ADUM3211TRZ-RL7原厂芯片

编辑-Z ADUM3211TRZ-RL7参数描述&#xff1a; 型号&#xff1a;ADUM3211TRZ-RL7 数据速率&#xff1a;10 Mbps 传播延迟&#xff1a;50 ns 脉冲宽度失真&#xff1a;3 ns 脉冲宽度&#xff1a;100 ns 输出上升/下降时间&#xff1a;2.5 ns 供电电流&#xff1a;2.6 mA …

Maven与spring学习

目录 该如何学习Maven&#xff0c;是先该学习spring还是先学习Maven 能讲一下该如何学习Maven吗&#xff1f; 火狐浏览器有能让网页翻译成为中文的插件吗 秋田和柴犬是同一个狗吗 该如何学习Maven&#xff0c;是先该学习spring还是先学习Maven 学习Maven可以与学习Spring同…

一键安装k8s脚本

服务器配置 节点(华为云服务器)配置master 2vCPUs | 4GiB | s6.large.2 CentOS 7.8 64bit node1 2vCPUs | 8GiB | s6.large.4 CentOS 7.8 64bit node2 2vCPUs | 8GiB | s6.large.4 CentOS 7.8 64bit 1.master节点安装脚本&#xff1a;install_k8s_master.sh。 sh文件上传到…

2023数维杯数学建模ABC题思路分析

占个位置吧&#xff0c;开始在本帖实时更新数维杯数学建模赛题思路代码&#xff0c;文章末尾获取&#xff01; 持续为更新参考思路 赛题思路 已完成全部可以领取&#xff0c;详情看文末&#xff01;&#xff01;&#xff01; 数维杯A题思路 A题是这次比赛比较难的题目&…

windows下升级nodejs

重新安装新版nodejs 重新安装nodejs然后设置环境变量 安装yarn npm install -g yarn --registryhttps://registry.npm.taobao.org yarn config set registry https://registry.npm.taobao.org -g yarn config set sass_binary_site http://cdn.npm.taobao.org/dist/node-sa…

大数据如何助力营销(2)用户画像

用户画像是指根据用户的数据&#xff0c;构建出用户的特征和兴趣&#xff0c;从而对用户进行分类和个性化的过程。用户画像可以帮助营销人员更有效地触达目标客户&#xff0c;提高营销效果和转化率。 用户画像的价值 用户画像的价值主要体现在以下几个方面&#xff1a; 提升用…

信号signal编程测试

信号会打断系统调用&#xff0c;慎用&#xff0c;就是用的时候测一测。 下面是信号的基础测试 信号 信号&#xff08;signal&#xff09;机制是UNIX系统中最为古老的进程之间的通信机制。它用于在一个或多个进程之间传递异步信号。信号可以由各种异步事件产生&#xff0c;例如…

计算机毕业论文内容参考|基于三维建模和卷积神经网络的人脸转正的技术设计

文章目录 导文文章重点摘要前言绪论课题背景国内外现状与趋势课题内容相关技术与方法介绍技术分析技术设计人脸转正方法卷积神经网络的训练和优化数据预处理技术实现总结与展望本文总结导文 基于java开发汽车销售系统资料 文章重点 摘要 在实际应用中,人脸图像往往具有旋转、…

vue+elementui+nodejs校园高校餐厅点餐及订餐菜品推荐评价系统6927k

传统的销售模式&#xff0c;在实体店的紧跟式的销售模式&#xff0c;会给消费者一种不自由&#xff0c;被监视的感觉。餐厅点餐及推荐系统&#xff0c;紧跟数据时代的步伐&#xff0c;使用nodejs开发语言&#xff0c;配备MySQL数据库。扎根于实际问题所开发出来的一套系统。这个…