当前位置: 首页 > news >正文

栈虚拟机和寄存器虚拟机,有什么不同?

本来这节内容是打算直接讲字节码指令的,但讲之前又必须得先讲指令集架构,而指令集架构又分为两种,一种是基于栈的,一种是基于寄存器的。

那不妨我们这节就单独来讲讲栈虚拟机和寄存器虚拟机,它们有什么不同,以及各自的优缺点。

栈和寄存器

关于栈这个数据结构,我们前面曾讲过,戳链接直达。

寄存器(Register)是中央处理器(CPU)内用来暂存指令、数据和地址的存储器,也是 CPU 中读写最快的存储器。

图片来源于cxuan

图片来源于cxuan

从硬件层面来说,栈位于内存当中,而寄存器位于 CPU 当中,这也是为什么,我们通常会说,基于寄存器架构的虚拟机会比基于栈的虚拟机快的原因。

基于栈的虚拟机

前面我们讲 JDK 的发展历程时,提到了 Hotspot VM,它是血缘最正统的 Java 虚拟机。

 

HotSpot VM 是基于栈的一种虚拟机,当 Java 程序运行时,HotSpot VM 加载编译后的字节码文件(也就是.class 文件),其解释器或JIT编译器会读取文件中的字节码指令,将它们解释(或编译)为机器码。

方法调用和执行过程中的数据(如局部变量和中间结果)会存储在栈(操作数栈,下面会讲)中,字节码指令操作这些数据,然后执行程序逻辑。

下面这幅图我们之前在讲JVM 是如何运行 Java 代码的时候讲过。

 

main 方法被执行的时候,JVM 会创建一个栈帧(Stack Frame),通过存储局部变量表、操作数栈、动态链接、方法出口等信息来支撑和完成方法的执行,栈帧就是虚拟机栈中的子单位。

 

栈帧本身也是一种栈结构,用于支持虚拟机进行方法调用和方法执行,遵循 LIFO 的原则,每个栈帧都包含了一个方法的运行信息,每个方法从调用到执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈和出栈的过程。

图片来源于网络,作者浣熊say

图片来源于网络,作者浣熊say

虚拟机栈是线程私有的,每个线程都有自己的 Java 虚拟机栈。方法调用时都会创建一个新的栈帧,该栈帧被推入虚拟机栈,成为当前活动栈帧。

  • 入栈:方法调用时,虚拟机栈会为这个方法分配一个栈帧,这个栈帧被压入虚拟机栈,成为当前的活动栈帧。PC 寄存器指向当前栈帧的指令,执行方法的指令序列从该地址开始。
  • 出栈:方法执行完成后,对应的栈帧会被移除,控制权回到前一个栈帧,前一个栈帧中的返回值成为当前活动栈帧的一个操作数,继续执行。

其中的操作数栈(Operand Stack)也是一种栈结构,用于保存方法执行时的中间结果、参数和返回值。当一个方法刚刚开始执行的时候,这个方法的操作数栈是空的。

在方法执行的过程中,操作数栈被用于执行各种字节码指令。例如,将两个数字相加的指令会从操作数栈中弹出两个数字,将它们相加,然后将结果压入操作数栈中。

另外,操作数栈的内容是临时的,它的生命周期和方法的生命周期是一样的,当方法执行结束后,操作数栈也会被销毁。

 

R 大曾在知乎的贴子里提到过:

VM 当初设计的时候非常重视代码传输和存储的开销,因为假定的应用场景是诸如手持设备、机顶盒之类的嵌入式应用,所以要代码尽量小;外加基于栈的实现更简单(无论是在源码编译器的一侧还是在虚拟机的一侧),而且主要设计者 James Gosling 的个人经验上也对这种做法非常熟悉(例如他之前实现过 PostScript 的虚拟机,也是基于栈的指令集),所以就选择了基于栈。

我们简单来看一下基于栈的虚拟机方法执行的过程,以下面的代码为例:

int a = 33;
int b = 44;
int c = a + b;

通过 javap -c Main 命令可以查看对应的字节码,如下所示:

Compiled from "Main.java"
public class com.github.paicoding.forum.test.javabetter.jvm.Main {public static void main(java.lang.String[]);Code:0: bipush        332: istore_13: bipush        445: istore_26: iload_17: iload_28: iadd9: istore_310: return
}

我们用图来说明指令执行的过程,大致如下。

 

  • iload_0 将 33 压入操作数栈中
  • iload_1 将 44 压入操作数栈中
  • iadd 将操作数栈中的 33 和 44 弹出,相加后将结果 77 压入操作数栈中
  • istore_2 将栈顶的 77 弹出,存入局部变量表中下标为 2 的位置

关于字节码指令的具体释义,我们放到下一节去细讲,这里主要是带大家体会一下基于栈的虚拟机和基于寄存器的虚拟机之间的差别。

基于寄存器的虚拟机

那除了有基于栈的虚拟机实现,当然也有基于寄存器的虚拟机实现,比如 LuaVM,负责执行 Lua 语言,一门轻量级的脚本语言,可戳链接了解。

5.0 之前的 Lua 其实是用基于栈的指令集,到 5.0 才改为用基于寄存器的。出于两点考虑,一是减少数据移动次数,降低数据迁移带来的拷贝开销;二是减少虚拟指令条数,提高指令执行效率。

 

好,我们就基于 lua 来看一下基于寄存器的虚拟机方法执行的过程。

第一步,安装 lua,这里我用的是 macOS,直接用 brew 安装就好了。

brew install lua

Windows 用户可以查看这个文档:lua-users wiki: Building Lua In Windows For Newbies

也可以通过 Lua for Windows 来完成安装:

Releases · rjpcomputing/luaforwindows · GitHub

我们来编写一段简单的 lua 代码,保存为 example.lua。

local a = 33
local b = 44
local c = a + b

然后查看字节码指令。

luac -l example.lua

结果如下:

 

main <example.lua:0,0> (6 instructions at 0x600002144080)
0+ params, 3 slots, 1 upvalue, 3 locals, 0 constants, 0 functions

这是函数的描述,表示这是 example.lua 文件中的主函数。它包含 6 条指令。函数不接受参数(0+ params),有 3 个本地变量槽位(3 slots),1 个闭包变量(1 upvalue),3 个本地变量(3 locals),没有常量(0 constants)和内部函数(0 functions)。

接下来是具体的指令:

  1. VARARGPREP 0:准备变长参数,用于处理传入的参数。
  2. LOADI 0 33:将整数 33 加载到寄存器 0。
  3. LOADI 1 44:将整数 44 加载到寄存器 1。
  4. ADD 2 0 1:将寄存器 0 和寄存器 1 中的值相加,并将结果存放在寄存器 2。对应于脚本中两个数值的加法操作。
  5. MMBIN 0 1 6; add:这是一个元方法(metamethod)调用,用于处理加法操作。这指示 Lua 虚拟机查找并执行 add 元方法。元方法是 Lua 中用于重载标准操作符的特殊方法。
  6. RETURN 3 1 1; 0 out:返回操作,将寄存器 3 中的值作为返回值。1 1 表示从寄存器 3 返回一个值,0 out 指没有额外的返回值。

小结

基于栈的优点是可移植性更好、指令更短、实现起来简单,但不能随机访问栈中的元素,完成相同功能所需要的指令数也比寄存器的要多,需要频繁的入栈和出栈。

基于寄存器的优点是速度快,有利于程序运行速度的优化,但操作数需要显式指定,指令也比较长。

相关文章:

栈虚拟机和寄存器虚拟机,有什么不同?

本来这节内容是打算直接讲字节码指令的&#xff0c;但讲之前又必须得先讲指令集架构&#xff0c;而指令集架构又分为两种&#xff0c;一种是基于栈的&#xff0c;一种是基于寄存器的。 那不妨我们这节就单独来讲讲栈虚拟机和寄存器虚拟机&#xff0c;它们有什么不同&#xff0…...

Windows下基于fping进行批量IP测试

fping是Linux下一个很好用的IP测试工具&#xff0c;结合代码可以完成批量的IP测试&#xff0c;在网络调试中用途很广。本文是基于fping for Windows结合bat批处理&#xff0c;定制的测试脚本样例。 一、程序信息 本次测试使用fpingV5.1 for Windows版&#xff0c;版本信息如下…...

一款实用的Word文档图片转换与水印保护工具

目录 前言软件功能简介软件实现方法及关键代码 1. Word 文档转图片的实现2. 图片水印添加功能3. 生成数字指纹&#xff08;哈希值&#xff09;4. 保存图片信息到 JSON 文件 软件的实际使用场景软件操作指南 1. 下载和安装2. 操作流程 总结 1&#xff0c;前言 在日常办公和内…...

优化用于传感应用的衬底集成波导技术

ANSYS HFSS 是一款功能强大的电磁仿真软件&#xff0c;支持为微流体生物传感器应用设计和分析衬底集成波导 &#xff08;SIW&#xff09; 技术。它为快速设计优化、材料选择、系统集成和虚拟原型制作提供了一个强大的平台。借助 ANSYS HFSS&#xff0c;研究人员和工程师可以高效…...

Java多态特性的向上转型

Java的多态特性通过向上转型来实现。向上转型指的是将子类对象赋值给父类引用变量的操作。这样做的好处是可以使用父类引用变量来调用子类对象的方法。 例如&#xff0c;有一个父类Animal和一个子类Dog&#xff0c;可以这样进行向上转型&#xff1a; Animal animal new Dog(…...

C++ 判断语句的深入解析

C 判断语句的深入解析 C 是一种广泛使用的编程语言&#xff0c;以其高效性和灵活性著称。在 C 中&#xff0c;判断语句是控制程序流程的关键组成部分&#xff0c;它们允许程序根据不同的条件执行不同的代码路径。本文将深入探讨 C 中的判断语句&#xff0c;包括 if、else if、…...

15分钟学 Go 第 33 天:项目结构

第33天&#xff1a;项目结构 目标&#xff1a;了解Go项目的典型结构 在Go语言的开发中&#xff0c;项目结构的合理性直接影响着代码的可维护性、可扩展性和团队协作效率。本篇文章将深入探讨Go语言的典型项目结构&#xff0c;并提供实际示例代码和相关的流程图。 一、Go项目…...

conda迁移虚拟环境路径

方法一&#xff1a;使用软连接 ln -s ~/Anaconda3/envs /new/path/envs 方法二&#xff1a;修改~/.condarc文件 1.打开~/.condarc文件 #添加下面参数 envs_dirs: - /newpath/anaconda3/envs pkgs_dirs: - /newpath/anaconda3/pkgs 2. source ~/.bashrc 3.查看是否成功con…...

(八)JavaWeb后端开发——Tomcat

目录 1.Web服务器概念 2.tomcat 1.Web服务器概念 服务器&#xff1a;安装了服务器软件的计算机服务器软件&#xff1a;接收用户的请求&#xff0c;处理请求&#xff0c;做出响应web服务器软件&#xff1a;在web服务器软件中&#xff0c;可以部署web项目&#xff0c;让用户通…...

yocto中通常不直接修改提供的recipes的bb文件

不直接在 Yocto 官方提供的 recipe 中修改 通常是创建新的 metadata 和 recipe 来配置相关软件编译等过程 主要有以下几个原因&#xff1a; 1. 便于维护和升级 隔离自定义修改&#xff1a;Yocto 官方的 recipe 可能会随着版本更新而变化。如果直接修改官方 recipe&#xff0…...

智能座舱相关术语全解及多模态交互在智能座舱中的应用

文章目录 座舱相关术语全解1. 智能座舱2. UFS3. 多模态交互4. 3D虚拟引擎5. AR/VR6. GNSS7. TTS8. DPU9. 摄像头10. 屏幕/显示器11. 音频12. 无线连接13. 其他组件 多模态交互在智能座舱中有以下一些应用 座舱相关术语全解 1. 智能座舱 智能座舱&#xff08;intelligent cabi…...

【Fastjson反序列化漏洞:深入了解与防范】

一、Fastjson反序列化漏洞概述 Fastjson是一款高性能的Java语言JSON处理库&#xff0c;广泛应用于Web开发、数据交换等领域。然而&#xff0c;由于fastjson在解析JSON数据时存在安全漏洞&#xff0c;攻击者可以利用该漏洞执行任意代码&#xff0c;导致严重的安全威胁。 二、F…...

【OJ题解】C++实现反转字符串中的每个单词

&#x1f4b5;个人主页: 起名字真南 &#x1f4b5;个人专栏:【数据结构初阶】 【C语言】 【C】 【OJ题解】 题目要求&#xff1a;给定一个字符串 s &#xff0c;你需要反转字符串中每个单词的字符顺序&#xff0c;同时仍保留空格和单词的初始顺序。 题目链接: 反转字符串中的所…...

万字长文详解Hive聚合函数 grouping sets、cube、rollup原理、语法、案例和优化

目录 原理与语法 使用场景 多维度报表生成 复杂的数据分析 实际案例 原理与语法 与GROUPINGSETS的区别 实际案例 原理与语法 与CUBE的对比 实际案例 执行效率比较 优化建议 Hive提供了三个强大的高级聚合函数: GROUPING SETS 、 CUBE 和 ROLLUP ,用于处理复杂的…...

数列分块入门

本期是数列分块入门。其中的大部分题目来自hzwer在LOJ上提供的数列分块入门系列。 Blog:here (其实是对之前分块的 blog 的整理补充) sto hzwer orz %%% [转载] ---------------------------------------------------------------------------------…...

SPRD Android 14 Launcher 3 中添加长按桌面图标启动自由窗口模式功能

本文将介绍如何在SPRD Android 14 Launcher 3 中实现一个功能,使用户可以通过长按应用图标来启动自由窗口模式。这一功能的实现将提升多任务处理能力和应用使用体验。 修改的文件列表 以下是主要涉及的文件及其修改内容: QuickstepLauncher.java:添加自由窗口快捷方式的支…...

WebSocket详解:从前端到后端的全栈理解

文章目录 前言一、WebSocket简介1.1 WebSocket的特点 二、WebSocket的工作原理2.1 握手过程2.2 数据传输 三、WebSocket在前端的应用四、WebSocket在后端的应用五、WebSocket的局限与解决方案结语 前言 随着互联网技术的发展&#xff0c;传统的HTTP协议在某些场景下的局限性逐…...

SOLIDWORKS 2025加快装配体设计 确保可制造性

在快速变化的制造业环境中&#xff0c;SOLIDWORKS作为一款CAD软件&#xff0c;始终致力于提供有效、智能且可靠的解决方案&#xff0c;以满足设计师和工程师对装配体设计的多样化需求。随着SOLIDWORKS 2025版本的发布&#xff0c;其在加快装配体设计、确保可制造性方面取得了显…...

简单题:计算从位置 x 到 y 的最少步数| 豆包MarsCode AI刷题

题目解析&#xff1a;计算从位置 x 到 y 的最少步数 题目描述 题目要求从整数位置 x 移动到整数位置 y&#xff0c;每一步可以将当前位置增加或减少&#xff0c;且每步的增加或减少的值必须是连续的整数。首末两步的步长必须是 1。要求求出从 x 到 y 的最少步数。 思路分析 …...

HTML 基础标签——表单标签<form>

文章目录 1. `<form>` 标签:定义表单容器2. `<input>` 标签:多用途输入控件3. `<textarea>` 标签:多行文本输入框4. `<select>` 标签:下拉选择框5. `<option>` 标签:下拉菜单选项6. `<button>` 标签:按钮元素7. `<label>` 标签…...

LeetCode 每日一题 2024/10/28-2024/11/3

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 10/28 685. 冗余连接 II10/29 3211. 生成不含相邻零的二进制字符串10/30 3216. 交换后字典序最小的字符串10/31 3165. 不包含相邻元素的子序列的最大和11/1 3259. 超级饮料…...

基于Spring Boot和Vue的电子商城系统功能设计

基于Spring Boot和Vue的电子商城系统功能设计 该系统是一个基于Spring Boot和Vue框架的电子商城平台&#xff0c;包含前台商城和后台管理系统。系统功能设计包括用户购物体验和管理员管理功能&#xff0c;支持商品的分类展示、收藏、购物车和订单管理等模块。以下是系统功能的简…...

成都睿明智科技有限公司正规吗靠谱吗?

在这个短视频风起云涌的时代&#xff0c;抖音电商以其独特的魅力&#xff0c;成为了无数商家竞相追逐的新蓝海。而在这片浩瀚的商海中&#xff0c;成都睿明智科技有限公司犹如一艘装备精良的航船&#xff0c;引领着众多企业破浪前行&#xff0c;探索抖音电商的无限可能。今天&a…...

【天线&化学】航拍图屋顶异常检测系统源码&数据集全套:改进yolo11-ContextGuided

改进yolo11-ContextGuided等200全套创新点大全&#xff1a;航拍图屋顶异常检测系统源码&#xff06;数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.11.01 注意&#xff1a;由于项目一直在更新迭代&#xff0c;上面“1.图片效果展示”和“2.视频效果展示”展示的系…...

【回忆】JavaScript 中的 Map 有哪些方法

在 JavaScript 中&#xff0c;Map 对象是一种键值对的集合&#xff0c;类似于对象&#xff0c;但“键”可以是任何数据类型&#xff08;对象或原始值&#xff09;。Map 提供了多种方法来操作这些键值对。以下是 Map 对象的一些常用方法&#xff1a; 创建和初始化 new Map(): …...

Chrome与夸克的安全性对比

在当今数字化时代&#xff0c;浏览器的安全性对于用户来说至关重要。Chrome和夸克作为两款流行的浏览器&#xff0c;各有其特点和优势。本文将对这两款浏览器的安全性进行详细对比&#xff0c;帮助用户更好地了解它们之间的差异。&#xff08;本文由https://www.chromegw.com/的…...

使用Python可视化支持向量机(SVM)

支持向量机&#xff08;SVM&#xff09;是用于分类和回归任务的强大监督学习模型。它们受欢迎背后的一个关键因素是它们有效处理线性和非线性数据的能力。在本文中&#xff0c;我们将探索使用Python和流行的库&#xff08;如scikit-learn和Matplotlib&#xff09;可视化SVM。 …...

C++泛型编程

一、什么是泛型编程 泛型编程 是一种编程范式&#xff0c;它通过编写可以处理多种数据类型的代码来实现代码的灵活复用。泛型编程主要通过模板来实现。 比如我们日常使用的容器类型vector就应用了模板来实现其通用性&#xff0c;我们在使用时可以通过传入型别创建对应的动态数…...

【论文分享】利用大量街景图片研究街道空间质量与建筑环境属性之间的关联

本研究通过有序逻辑回归模型&#xff0c;结合街景图片和街道数据&#xff0c;分析了街道空间质量与建筑环境属性的关系。通过Kappa分析和相关性分析&#xff0c;确定了影响街道空间质量的因素&#xff0c;并绘制了质量分布图。这些因素与街道质量的不同维度相关联&#xff0c;对…...

【Linux第七课--基础IO】内存级文件、重定向、缓冲区、文件系统、动态库静态库

目录 引入内存级文件重新使用C文件接口 -- 对比重定向写文件读文件文件流 认识文件操作的系统接口open参数 -- flagflag的内容宏的传参方式 open关闭文件写文件读文件结论 引入文件描述符fd、对文件的理解理解一切皆文件方法集文件fd的分配规则 重定向代码的重定向输入重定向输…...