杭州网站设计渠道/品牌广告语经典100条
大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 033 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进一步完善自己对整个 Java 技术体系来充实自己的技术栈的同学。与此同时,本专栏的所有文章,也都会准备充足的代码示例和完善的知识点梳理,因此也十分适合零基础的小白和要准备工作面试的同学学习。当然,我也会在必要的时候进行相关技术深度的技术解读,相信即使是拥有多年 Java 开发经验的从业者和大佬们也会有所收获并找到乐趣。
–
在当今的软件开发领域,Java 虚拟机(JVM)扮演着至关重要的角色,它不仅是 Java 语言的运行时环境,也是跨平台应用的基石。理解 JVM 的原理和功能,对 Java 开发者来说至关重要。本篇文章将带你全面了解 JVM 的起源、结构和工作原理,帮助你奠定扎实的基础,为后续深入研究 JVM 的各个方面做好准备。
文章目录
- 1、对于 Java 虚拟机的认知
- 1.1、Java 虚拟机(Jvm) 与 Java 语言的关系
- 1.2、one write run anywhere(一次编写到处运行)
- 1.2.1、C 语言的编译过程
- 1.2.2、如何理解汇编语言
- 1.2.3、C 语言为什么不能跨平台
- 1.2.4、Java 为什么可以跨平台
- 2、Java 虚拟机的基础知识
- 2.1、Java 虚拟机概述
- 2.2、JVM、JRE、JDK的关系
- 2.3、Java 虚拟机的结构组成
1、对于 Java 虚拟机的认知
1.1、Java 虚拟机(Jvm) 与 Java 语言的关系
在我们系统的认识 Java 虚拟机前,我们应该明确一个事实,即:“Java 虚拟机不和包括 Java 在内的任何一种语言绑定,它只与 ‘Class文件’ 这种特定的二进制文件格式所关联,Class 文件中包含了 Java 虚拟机指令集和符号表以及若干其他辅助信息”。
所以 “Java 虚拟机” 这一命名本身有一定的误导性,Java 虚拟机和 Java 语言并不存在必要的联系,将其称作 “Class 文件虚拟机” 可以更适合理解。
Java 在 1997 年发布规范文档的时候,也刻意的将 Java 的规范拆分为《 Java 语言规范(The Java Language Specification)》与 《Java 虚拟机规范(The Java Virtual Machine Specification)》两部分。
Java 语言规范 & Java 虚拟机规范:https://docs.oracle.com/javase/specs/
Java 虚拟机是语言无关性的,作为一个通用的、与机器无关的执行平台,任何其他语言的实现都可以将 Java 虚拟机作为其运行的基础,以 Class 文件作为他们产品的交付媒介。
例如,使用 Java 编译器可以把 Java 代码编译为存储字节码的 Class 文件,使用 JRuby 等其他语言的编译器一样可以把它们的源程序代码编译成 Class 文件。虚拟机丝毫不关心 Class 的来源是什么语言,它与程序语言之间的关系如图所示:
1.2、one write run anywhere(一次编写到处运行)
在我们初次接触 Java 时,都不可不避免的了解到,Java 的一个优势,也是 Java 刚推出时的宣传语:“one write run anywhere(一次编写到处运行)”,在这句话中,突出了 Java 虚拟机核心的思想,Java 虚拟机是与平台无关的,或者说 Java 虚拟机具有平台无关性!
1.2.1、C 语言的编译过程
既然 Java 虚拟机具有平台无关性,那么什么是平台有关性呢,我们先来看一下,C 语言的执行过程:
#include <stdio.h>
int main()
{printf("hello world");return 0;
}
这是一个 C 语言的程序,最终的至执行结果是打印一行 “hello world” 字符串,我们知道,计算机里的世界里只有 “0” 和 “1”,那以上的 C 程序是如何转换为 “0” 和 “1” 的呢?
以上 C 程序的编译过程:
我们分阶段来讨论:
- 首先是 “预处理阶段” :预处理器(cpp)会将头文件(# 开头的行)展开,将宏名替换为字符串,并将注释去掉;
- 接下来是 “编译阶段” :编译器(ccl)将修改后的
.c
文件,翻译为.s
文件,即汇编程序; - 再然后是 “汇编阶段” :汇编器(as)将
.s
文件翻译成.o
文件,这就是机器语言指令,二进制文件; - 在最后是 “链接阶段” :链接器(ld)将
.o
文件中的函数库对应的代码组合到最终目变文件中,这就是.out
文件了。
1.2.2、如何理解汇编语言
作为一个插曲,在这里阐述一下笔者对于汇编语言的理解。
什么是汇编语言,其实就是因为计算机只能识得 “0” 和 “1”,在计算机刚被发明时,科学家们只能通过向计算机输入 0|1 代码的方式(通过穿孔纸带,有孔 1,无孔 0),来运行计算任务,但是这样的效率实在太慢了,所以汇编语言就被发明出来,用于简化程序的编写。
比如计算 1+1
,两个 “1” 数据使用 0x0001
来表示,而 “加” 操作,放在 CPU 中,可以是 0xa90df
(这个是胡乱写的),这个二进制代表的加操作能被计算机识别。而因为这个加操作对于 CPU 来说,编码的 0xa90df
格式是固定的。所以可以直接一个助记符 add
来表示,这样科学家们写程序就方便多了。而这就是汇编程序的由来。因为汇编程序完成之后,可以再有一个专门的程序(就是要上文中所说的汇编器)来把编写的汇编程序编译成 “0” 和 “1”,这样计算机也可以识别了,而汇编语言本身也方便了程序的编写和阅读。
编写汇编比直接编写二进制方便高效了太多。但是随着计算任务的复杂,程序的规模越来越庞大,使用汇编程序也很累啊,那么是否有更简单的方式呢?所以科学家们发明了高级语言(比如 C,lisp 等),在编写程序的时候,使用 C。语言等编写,然后再使用编译器将 C 语言程序翻译成汇编程序,汇编程序再使用汇编器编译成 “0” 和 “1”,这样,CPU 能识别的东西没有变化,但是对于编写程序的人,确实方便了很多。
通过以上的描述,我们就知道了高级语言的大概由来。也明白了我们所编写的各种高级语言,到了最后,其实都是转化为二进制执行。
1.2.3、C 语言为什么不能跨平台
在对汇编语言再一次理解之后,我们回到正题,即为什么 C 语言不具备平台无关性,或者说为什么 C 语言为什么不能跨平台。
直接二进制格式的程序,我们称之为本地机器码(native code)。而类似那些 add
之类的助记符,以及汇编的编写格式或标准,我们称之为指令集。
但是问题的关键来了。不同公司所生产的 CPU 芯片。他们所使用的指令集不同啊,这种芯片设计的事情,又不像 TCP/IP 协议那样,有国际统一的标准,甚至像 Intel 所代表的复杂指令集,和 ARM 为代表的精简指令集,它们指令集的设计思路就是不一样的。
所以我们 C 语言最后编译出来的的二进制文件,不同的 CPU 上识别的意义是完全不同的。
此外,还有一种场景,就是一段 C 语言的程序,我们编写一个 .c
的文件后,将其拿到另外一个操作系统|CPU 平台去执行,是否会成功呢?成功了之后那么是否可以说明 C 语言具有跨平台性呢,很多人存在着不同的看法,对此,笔者是这样认为的:
- C 语言并非不能跨平台(CPU 或者操作系统),准确的说是 C 语言编译出的程序无法二进制跨平台;
- 不同环境下,C 语言的标准有差别,比如不同平台的 int 类型可能是 16 位表示也可能是 32 位表示,但笔者认为这种情况是可以有多种方式去规避的,随意最终的结论还是 C 语言不能跨平台是特指二进制跨平台。
那有没有一种办法,能够让高级语言实现(二进制)跨平台的运行呢?
思考实际编程中的一个场景,我们前端需要处理的某个数据是 A 格式,但是后台只能提供B格式的数据,那我们怎么办?很简单啊。写个接口,把 B。格式转化为 A 格式。这就是设计模式当中的适配器设计模式。
关于跨平台也是一样的道理。CPU 的指令集不同, 不同平台编译出来的结果格式都不同,那么我们可以在各个平台上运行虚拟机,然后我们制定某种编译结果的输出格式,我们的输出了某种格式的结果,直接在虚拟机上运行。 这就是 Java 采取的方式。
1.2.4、Java 为什么可以跨平台
这是 Java 版本的 “Hello World”:
public static void main(String[] args) {System.out.println("Hello World!");
}
这段 Java 程序编译出来的结果是 hello.class
,换句话说,它输出的结果是 Class 文件格式(也叫字节码存储格式)。
这其实就是 Java 虚拟机定义的二进制格式,这种我们称之为字节码(ByteCode),是 Java 虚拟机所能运行的格式。类似本地机器码可以反编译成汇编,这种二进制也可以反编译成更容易阅读的格式。
而各个平台的 Java 虚拟机 是不同的。但是我们编写的 Java 程序 统一编译成特定格式的 Class 文件格式,然后 Class 文件可以在各个不同平台的 Java 虚拟机上运行,当然运行结果肯定也是一致的,至于各个不同平台之间的差异,这是那些编写 Java 虚拟机的人去考虑的事情。
通过这种方式,我们的 Java 程序就实现了跨平台。
2、Java 虚拟机的基础知识
2.1、Java 虚拟机概述
Java 虚拟机(英语:Java Virtual Machine,缩写:JVM),一种能够执行 Java 字节码(Class 文件)的虚拟机,以堆栈结构机器来进行实做。最早由 Sun 公司所研发并实现第一个实现版本,是 Java 平台的一部分,能够执行以 Java 语言所写的软件程序。
Java 虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 Java 虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。通过对中央处理器(CPU)所执行的软件实现,实现能执行编译过的 Java 程序码(Applet 与应用程序)。
作为一种编程语言的虚拟机,实际上不只是专用于 Java 语言,只要生成的编译文件符合 JVM 对加载编译文件格式要求,任何语言都可以由 JVM 编译运行。此外,除了甲骨文,也有其他开源或闭源的实现。
2.2、JVM、JRE、JDK的关系
JVM 是 Java 程序能够运行的核心。但需要注意,JVM 自己什么也干不了,你需要给它提供生产原料(Class 文件)。 仅仅是 JVM,是无法完成一次编译,处处运行的。它需要一个基本的类库,比如怎么操作文件、怎么连接网络等。
而 Java 体系很慷慨,会一次性将 JVM 运行所需的类库都传递给它。JVM 标准加上实现的一大堆基础类库,就组成了 Java 的运行时环境,也就是我们常说的 JRE。
对于 JDK 来说,就更庞大了一些。除了JRE,JDK还提供了一些非常好用的小工具,比如 javac、java、jar 等。它是 Java 开发的核心。 我们也可以看下 JDK 的全拼,JavaDevelopmentKit。
JVM、JRE、JDK 它们三者之间的关系,可以用一个包含关系表示:
2.3、Java 虚拟机的结构组成
Java 虚拟机整体组成可分为四个部分:类加载器(Class Loader)、运行时数据区(Runtime Data Area)、执行引擎(Execution Engine)、本地库接口(Native Interface)
- 类加载器:负责从字节码 Class 文件中,加载 Class 信息到运行时数据区的方法区;
- 运行时数据区:存放 Jvm 在执行 Java 程序时相关数据的区域;
- 执行引擎:将字节码翻译成底层系统指令再交由 CPU 去执行;
- 本地库接口:执行过程中可能需要调用到其他语言(比如 C 语言)的本地接口。
Ps:Javac 是收录于 Jdk 中的 Java 语言编译器。该工具可以将 .java
源文件编译为 Class 文件(.class
文件)。
在程序被执行之前,Java 前, Java 代码会被先转换成字节码 Class 文件,Jvm 首先通过一定的方式使用「类加载器」把字节码文件加载到内存中「运行时数据区」,而字节码文件是 Jvm 提供的一套指令集规范,并不能直接交个底层操作系统去执行,因此需要特定的命令解析器「执行引擎」将字节码翻译成底层系统指令再交由 CPU 去执行,而这个过程中需要调用其他语言的接口「本地库接口」,来实现整个程序的功能,这就是这 4 个主要组成部分的职责与功能。
相关文章:

Java虚拟机:虚拟机介绍
大家好,我是栗筝i,这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 033 篇文章,在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验,并希望进…...
硬件面试经典 100 题(31~40 题)CRE4
31、多级放大电路的级间耦合方式有哪几种?哪种耦合方式的电路零点偏移最严重?哪种耦合方式可以实现阻抗变换? 有三种耦合方式:直接耦合、阻容耦合、变压器耦合。直接耦合的电路零点漂移最严重,变压器耦合的电路可以实现…...

ReactNative笔记(自用)
环境 ios更换gem镜像源: 查看当前源: gem sources -l 移除默认源: gem sources --remove https://rubygems.org/。添加新的源: 添加 Ruby China 的镜像源: gem source -a https://gems.ruby-china.com/或者添加其他镜像源。 清华大学的gem源: htt…...

嵌入式八股-面试30题(20240812)
TCP和UDP的区别是什么? **TCP(Transmission Control Protocol)**是面向连接的协议,提供可靠的、顺序的数据传输。它通过三次握手建立连接,并在数据传输过程中使用确认和重传机制来确保数据的正确性。TCP还支持流量控制和拥塞控制…...

单一职责原则(SRP)
目录 1、定义 2、优点 3、原则的重要性 4、 示例 5、注意事项 单一职责原则(Single Responsibility Principle, SRP)是面向对象设计中的一项重要原则,属于 SOLID 原则之一。它的核心思想是:一个类应该只有一个引起它变化的原因&am…...

骨传导耳机怎么选?分享五款资深用户都说好的骨传导耳机!
在追求健康生活的道路上,运动健身已成为一种时尚潮流,而音乐则是这场潮流中不可或缺的催化剂。然而,传统耳机在运动场景下的局限性日益凸显,难以满足运动者对自由与舒适的双重追求。正是基于这样的市场需求,骨传导耳机…...

【计算机网络——分组延时,丢失,吞吐量】
处理延时:1检查分组首部信息,决定将该分组导向何处所需时间。2检查比特级别的差错所需时间:分析这个分组是否出错,目标IP地址字段提取出来,查路由表……。 传播延时和传输延时:传输延时就是分组到链路所需…...

使用1panel 申请证书配置雷池站点
1.创建测试站点 2.使用1panel申请测试站点的自签名证书 ps:雷池支持自签的证书 关于如果选择网站的SSL证书 百度搜索 看起来是证书的问题 调整了参数重新申请一个证书上传 注意,如果文件上传错了,雷池会报错,如下图 再次访问配…...

4章7节:用R做数据重塑,数据去重和数据的匹配
在数据科学的分析流程中,数据重塑是一项非常重要的操作。数据的重塑通常指将数据从一种形式转换为另一种形式,以满足后续分析的需求。R语言提供了丰富的工具和函数来帮助用户高效地进行数据重塑操作。本文中,我们将深入探讨数据重塑的概念及其…...

大数据面试SQL(七):累加刚好超过各省GDP40%的地市名称
文章目录 累加刚好超过各省GDP40%的地市名称 一、题目 二、分析 三、SQL实战 四、样例数据参考 累加刚好超过各省GDP40%的地市名称 一、题目 现有各省地级市的gdp数据,求从高到低累加刚好超过各省GDP40%的地市名称,临界地市也需要。 例如: 浙江省…...

建议收藏!这4款设计师常用的素材管理软件,助你工作效率翻倍!
嘿,设计师们!你是否还在为那一堆堆散乱的素材头疼?每次灵感来袭,却要花费大量时间在层层文件夹中苦苦搜寻?别急,今天我就来给大家推荐4款超给力的素材管理软件,它们不仅能帮你轻松整理素材库&am…...

用于NLP领域的排序模型最佳实践
在自然语言处理(NLP)领域,用于排序任务的模型通常是指那些能够对文本进行排序、比较或评估其相关性的模型。这些模型可以应用于诸如文档排序、句子排序、问答系统中的答案排序等多种场景。在当前的研究和发展中,基于深度学习的方法…...

域名未备案的支付平台遭遇大攻击怎么办
域名未备案的支付平台遭遇大攻击怎么办?在当今数字化时代,支付平台的安全与稳定性是保障业务连续性和用户信任的关键。然而,对于因域名未备案而面临法律风险的支付平台来说,其安全挑战更为严峻。当这类平台遭遇大规模的网络攻击&a…...

【NI-DAQmx入门】LabVIEW数据采集基础应用程序框架
对于可管理规模的 LabVIEW 程序,分析现有程序或设计新程序的方法通常是从整体到具体,即从高级到低级的分析和设计。从一开始就直接深入细节可能会效率较低。 在设计阶段,开发人员首先将程序垂直划分为几个层级。从最顶层开始,他们…...

海山数据库(He3DB)源码详解:CommitTransaction函数源码详解
文章目录 海山数据库(He3DB)源码详解:CommitTransaction函数1. 执行条件2. 执行过程2.1 获取当前节点状态:2.2 检查当前状态:2.3 预提交处理:2.4 提交处理:2.5 释放资源:2.6 提交事务: 作者介绍…...

【网络】传输层TCP协议的报头和传输机制
目录 引言 报头和有效载荷 确认应答机制 捎带应答机制 超时重传机制 排序和去重 连接管理机制 个人主页:东洛的克莱斯韦克-CSDN博客 引言 TCP是传输层协议,全称传输控制协议。TCP报头中有丰富的字段以及协议本身会制定完善的策略来保证网络传输的…...

【活动报名】打造编程学习“知识宝库”:高效笔记记录与整理指南
如何高效记录并整理编程学习笔记? 在编程学习的旅程中,拥有一套高效的笔记记录和整理方法至关重要。以下将从三个方向为您详细介绍如何打造属于自己的编程学习“知识宝库”。 方向一:笔记工具选择 选择合适的笔记工具是高效记录编程学习笔记…...

使用Arduino IDE生成带有bootloader的烧录文件
使用Arduino IDE生成bin(烧录)文件 1、在“项目”中,选择“导出已编译的二进制文件” 2、在工程目录中,会出现“build”文件夹 3、在build文件夹中,有hex文件,以及包含bootloader的bin和hex文件 bin和h…...

搭建高可用OpenStack(Queen版)集群(九)之部署nova计算节点
一、搭建高可用OpenStack(Queen版)集群之部署计算节点 一、部署nova 1、安装nova-compute 在全部计算节点安装nova-compute服务 yum install python-openstackclient openstack-utils openstack-selinux -y yum install openstack-nova-compute -y 若yu…...

C# 字符串扩展方法
功能 1.判断一个字符串是否为null或者空字符串 2.判断一个字符串是否为null或者空白字符 3.判断一个字符串是否为数字 4.判断一个字符串是否为邮件 5.判断一个字符串是否为字母加数字 6.判断一个字符串是否为手机号码 7.判断一个字符串是否为电话号码 8.判断一个字符串是否为网…...

JookDB和MobaXterm下载安装使用
文章目录 1.使用背景2.MobaXterm的下载安装使用3.JooKDB的下载安装使用 1.使用背景 由于xshell和xftp等工具都是收费的,即使有破解版但是有的公司里不让用盗版的软件。可以使用MobaXterm来替代。 同理可使用JooKDB来代替收费的navicat 来连接数据库。 2.MobaXterm…...

Docker安装Nacos(详细教程)
Docker安装Nacos的步骤相对直接,但需要注意一些细节以确保安装成功。以下是一个详细的安装步骤指南: 1. 安装Docker 首先,确保你的系统中已经安装了Docker。如果尚未安装,你可以通过访问Docker的官方网站或使用包管理器…...

Pandas:提供了快速、灵活和表达式丰富的数据结构。
引言 Pandas是Python中最为广泛使用的数据分析和操作库之一,特别适用于处理结构化数据。该库的名称源自“Panel Data”的缩写,意为面板数据或多维数据。Pandas基于NumPy构建,继承了其高效的数组计算能力,并在此基础上进一步扩展&…...

强!小目标检测全新突破!检测速度快10倍,GPU使用减少73.4%
强!小目标检测全新突破,提出Mamba-in-Mamba结构,通过内外两层Mamba模块,同时提取全局和局部特征,实现了检测速度快10倍,GPU使用减少73.4%的显著效果! 【小目标检测】是近年来在深度…...

重修设计模式-创建型-原型模式
重修设计模式-创建型-原型模式 原型模式就是利用已有对象(原型)通过拷贝方式来创建对象的模式,达到节省对象创建时间的目的。适用于对象创建成本较大,且同一类的不同对象之间差别不大的场景。 比如一个对象中的数据需要经过复杂…...

S71200 - 编程 - 笔记
1 DEMO 1.1气阀控制 1.2 红绿灯 基于PLC红绿灯控制_哔哩哔哩_bilibili 2 介绍变量DB,M,I,Q的使用 在PLC编程中,通常会使用多种类型的变量来实现逻辑控制、数据存储和输入输出操作。以下是常见的PLC变量类型及其用途ÿ…...

【项目】畅聊天地博客测试报告
项目简介:本项目采用 SSM框架结合 Websocket 技术构建。用户通过简单的注册和登录即可进入聊天室,与其他在线用户实时交流。系统支持文字消息的快速发送和接收、消息实时推送,确保交流的及时性和流畅性。SSM 框架为项目提供了稳定的架构和高效…...

【Next】全局样式和局部样式
不同于 nuxt ,next 的样式绝大部分都需要手动导入。 全局样式 使用 sass 先安装 npm i sass -D 。 我们可以定义一个 styles 文件,存放全局样式。 variables.scss $fs30: 30px;mixin border() {border: 1px solid red; }main.scss use ./variables …...

关于Docker的详细介绍
Docker是一个开源的应用容器引擎,它允许开发者将应用程序及其依赖项打包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,实现虚拟化。以下是关于Docker的详细介绍: ### 一、Docker的定义 Docker是一…...

一台佳能G3811彩色喷墨打印机打印没颜色报5200的维修记录
一台佳能G3811彩色喷墨打印机,用户送修,称打印没有颜色,加电开机连电脑安驱动打印测试,确实没有颜色,于是清洗喷头结果打印机那个显示屏上 ,上来就报错P08,电脑提示5200; 话不多说,开始维修,仅记录当时的维修方法及步骤,其它未列出。。。 维修方法: 1、进维…...