图解JVM-1. JVM与Java体系结构
一、前言
在 Java 开发的广袤天地里,不少开发者都遭遇过令人头疼的状况。线上系统毫无征兆地卡死,陷入无法访问的僵局,甚至直接触发 OOM(OutOfMemoryError,内存溢出错误);面对 JVM 的 GC(Garbage Collection,垃圾回收)难题,满心困惑却不知从何下手;新项目上线时,面对纷繁复杂的 JVM 参数设置,只能无奈采用默认值,结果可能导致性能不佳。在面试中,背诵 JVM 原理概念容易,但被问及实际项目中的 JVM 参数调优、GC 和 OOM 问题解决策略时,却常常一脸茫然。
这种现象背后,反映出大部分 Java 开发人员的知识短板。很多人热衷于钻研 SSM、微服务等上层技术,却忽视了 Java 技术的核心 ——Java 虚拟机。实际上,核心类库的 API 如同数学公式,而 JVM 知识则是公式的推导过程。只有深入理解 JVM,才能在开发中如鱼得水,游刃有余地应对各种复杂问题。掌握 JVM 知识,不仅是应对面试的 “利器”,更是中高级程序员的必备技能,能够满足项目管理与调优的需求,还能让开发者在追求极客精神的道路上更进一步。
二、Java 及 JVM 简介
(一)Java 语言的发展历程与地位
回顾 Java 的发展轨迹,1990 年,Sun 计算机公司的 Green Team 在 Patrick Naughton、Mike Sheridan 及 James Gosling 的带领下,开发出最初名为 oak 的语言,后更名为 Java。1995 年,Java 和 HotJava 产品正式发布,Java 自此登上历史舞台。随后,JDK(Java Development Kit,Java 开发工具包)不断迭代更新,从 1996 年的 JDK 1.0,到 2019 年的 JDK 12,每一次版本升级都带来新的特性与改进。在 TIOBE 语言热度排行榜上,Java 长期名列前茅,这充分彰显了其在软件开发领域的重要地位。
(二)JVM:跨语言的强大平台
JVM 作为 Java 平台的关键支柱,具有卓越的跨语言特性。它不仅支持 Java 语言,Groovy、Scala、JRuby、Kotlin 等语言也能在 JVM 上运行。这是因为 JVM 只关注字节码文件,只要其他编程语言的编译结果符合 JVM 的内部指令集、符号表及辅助信息要求,就能被 JVM 识别并运行。不同编译器可以生成相同的字节码文件,且这些字节码文件具备跨 JVM 运行的能力。
随着 Java 7 的发布,JVM 通过 JSR - 292 规范,进一步拓展了对非 Java 语言编写程序的支持。以多语言混合编程为例,在一个项目中,并行处理可以用 Clojure 语言,展示层使用 JRuby/Rails,中间层采用 Java,各层语言交互顺畅,就像使用原生 API 一样便捷,这都得益于 JVM。围绕 JSR - 292 的一系列项目和功能改进,推动着 JVM 从 “Java 语言的虚拟机” 向 “多语言虚拟机” 转变。
三、虚拟机与 Java 虚拟机
(一)虚拟机的分类与特点
虚拟机(Virtual Machine)本质上是一款软件,用于执行虚拟计算机指令,可分为系统虚拟机和程序虚拟机。像 Virtual Box、VMware 这类系统虚拟机,是对物理计算机的全面仿真,能提供运行完整操作系统的软件平台。而程序虚拟机的典型代表便是 Java 虚拟机,它专为执行单个计算机程序而设计,执行的是 Java 字节码指令。无论是哪种虚拟机,在其上面运行的软件都受限于虚拟机提供的资源。
(二)Java 虚拟机的独特魅力
Java 虚拟机是执行 Java 字节码的虚拟计算机,拥有独立运行机制,其运行的字节码不一定由 Java 语言编译而来。JVM 平台的众多语言共享着它的跨平台性、出色的垃圾回收器以及可靠的即时编译器。Java 技术的核心就在于 JVM,所有 Java 程序都在 JVM 内部运行。
JVM 的主要作用是为二进制字节码提供运行环境,负责将字节码装载到内部,并解释或编译成对应平台的机器指令执行。每一条 Java 指令在 JVM 规范中都有详尽定义。同时,JVM 具有 “一次编译,到处运行”、自动内存管理和自动垃圾回收等显著特点。并且,JVM 运行在操作系统之上,与硬件没有直接交互,这也是其实现跨平台的关键所在。
四、JVM 的整体结构
HotSpot VM 是当下高性能虚拟机的杰出代表,采用解释器与即时编译器并存的架构。在这种架构下,解释器可以快速启动,对代码进行解释执行;而即时编译器则会在运行过程中,将热点代码编译成本地机器码,大大提高执行效率。正是得益于这种架构,Java 程序的运行性能今非昔比,足以与 C/C++ 程序相媲美。

五、Java 代码执行流程
Java 代码的执行是一个严谨且有序的过程。首先,Java 源文件(.java)通过 Java 编译器编译成字节码文件(.class)。字节码文件包含了 JVM 指令集、符号表以及其他辅助信息。接着,JVM 启动时,类加载器会将字节码文件加载到内存中。在运行时,解释器逐行解释执行字节码指令,如果遇到热点代码(频繁执行的代码),即时编译器会介入,将其编译成机器码,直接在底层硬件上高效运行。这个过程中,JVM 的内存管理系统负责分配和回收内存,垃圾回收器会自动清理不再使用的对象,确保内存的高效利用。

六、JVM 的架构模型
Java 编译器输入的指令流主要基于栈式指令集架构,与之相对的是基于寄存器的指令集架构。
基于栈式架构具有诸多优势:设计和实现相对简单,适合资源受限的系统;它避开了寄存器分配的难题,采用零地址指令方式分配;指令流中的指令大多是零地址指令,执行过程依赖操作栈,指令集较小,编译器容易实现;并且无需特定硬件支持,可移植性强,便于实现跨平台。不过,其缺点也较为明显,性能相对较低,实现相同功能往往需要更多指令。
基于寄存器架构则以 x86 二进制指令集为典型代表,像传统 PC 以及 Android 的 Davlik 虚拟机都采用这种架构。它的性能优秀,执行效率高,完成一项操作所需的指令更少。但它严重依赖硬件,可移植性较差。


以 2 + 3 的计算操作为例,基于栈的计算流程中,需要先将操作数压入栈,再进行计算,最后从栈中取出结果;而基于寄存器的计算流程则直接在寄存器中进行操作,效率更高。由于 Java 追求跨平台性,不同平台 CPU 架构差异大,所以选择了基于栈的架构。尽管如今嵌入式平台已不是 Java 程序的主流运行环境,但考虑到庞大的 Java 生态和兼容性,暂时不会更换为基于寄存器的架构。
七、JVM 的生命周期
(一)虚拟机的启动
Java 虚拟机的启动是通过引导类加载器(bootstrap class loader)创建一个初始类(initial class)来完成的,这个初始类由虚拟机的具体实现指定。引导类加载器负责加载 JVM 运行所需的核心类库,为后续的程序执行奠定基础。
(二)虚拟机的执行
当一个 Java 程序开始执行时,实际上是启动了一个 Java 虚拟机进程。在程序执行期间,JVM 持续运行,负责执行字节码指令、管理内存、进行垃圾回收等操作。只有当程序正常执行结束、遇到异常或错误异常终止、因操作系统错误导致进程终止,或者调用 Runtime 类或 System 类的 exit 方法、Runtime 类的 halt 方法(且 Java 安全管理器允许这些操作)时,JVM 才会停止运行。此外,JNI(Java Native Interface)规范中描述了使用 JNI Invocation API 加载或卸载 JVM 时的退出情况。
(三)虚拟机的退出
JVM 的退出情况较为多样。程序正常结束,自然会触发 JVM 退出;程序执行过程中若遭遇未处理的异常或错误,导致程序无法继续运行,JVM 也会异常终止;操作系统出现错误,影响到 JVM 进程时,JVM 同样会被迫终止。另外,通过代码主动调用特定方法,如 Runtime.getRuntime ().exit (0),也能使 JVM 退出。在 JNI 编程中,使用 JNI Invocation API 加载或卸载 JVM 时,也会涉及 JVM 的退出操作。

八、JVM 的发展历程
从Sun Classic VM到今天的HotSpot VM,JVM经历了多次重大更新和改进。如今,无论是服务器端应用还是移动开发,HotSpot VM都占据了主导地位。此外,Oracle的Graal VM以其跨语言全栈虚拟机的特性,预示着未来Java生态的新方向。
JVM 与 Java 体系结构是 Java 开发领域的核心知识,无论是在实际项目开发中的性能优化、问题排查,还是在面试中的脱颖而出,都具有不可替代的作用。深入学习和理解 JVM,能够让开发者站在更高的视角审视 Java 程序的运行机制,编写出更加高效、稳定的代码。
相关文章:
图解JVM-1. JVM与Java体系结构
一、前言 在 Java 开发的广袤天地里,不少开发者都遭遇过令人头疼的状况。线上系统毫无征兆地卡死,陷入无法访问的僵局,甚至直接触发 OOM(OutOfMemoryError,内存溢出错误);面对 JVM 的 GC&#…...
Word中的文档信息域
Word中的文档信息域 DocProperty包含文档信息的多个属性, 也可以自定义属性. 查看文档预定义的自定义属性 【文件】→【信息】→【属性】→【高级属性】 参考链接 WORD中文档属性域DocProperty的应用-CSDN博客 第06套 Word_哔哩哔哩_bilibili...
Linux中的权限问题(二)
一、不受权限约束的root 按照文件的使用者进行匹配后,即使权限是“---” root依旧可以正常进行读,写,运行 二、文件拥有者和所属组的更改方法以及限制 2.1chown:更改文件拥有者以及所属组 ①可以单独修改文件拥有者 chown[更…...
【ISO 14229-1:2023 UDS诊断全量测试用例清单系列:第十八节】
ISO 14229-1:2023 UDS诊断服务测试用例全解析(ResponseOnEvent_0x86服务) 作者:车端域控测试工程师 更新日期:2025年02月14日 关键词:UDS协议、0x86服务、事件响应、ISO 14229-1:2023、ECU测试 一、服务功能概述 0x86…...
Spring Boot自动装配:约定大于配置的魔法解密
#### 一、自动装配的哲学思考 在传统Spring应用中,开发者需要手动配置大量的XML或JavaConfig。Spring Boot通过自动装配机制实现了**约定大于配置**的设计理念,其核心思想可以概括为: 1. **智能预设**:基于类路径检测自动配置 2…...
[笔记.AI]大模型的蒸馏、剪枝、量化 | 模型压缩 | 作用与意义
上周简单整理了《deepseek-r1的不同版本(满血版、蒸馏版、量化)》,这次继续完善对其的认知——补充“剪枝”,并进一步整理蒸馏、剪枝、量化的作用与意义。 以下摘自与DeepSeek-R1在线联网版的对话 蒸馏、剪枝、量化是当前主流的三…...
【koa】05-koa+mysql实现数据库集成:连接和增删改查
前言 前面我们已经介绍了第二阶段的第1-4点内容,本篇介绍第5点内容:数据库集成(koamysql) 也是第二阶段内容的完结。 一、学习目标 在koa项目中正常连接数据库,对数据表进行增删改查的操作。 二、操作步骤 本篇文章…...
【数据结构】队列(Queue)
Queue 定义 Java中的队列(Queue)是一种先进先出(FIFO)的数据结构。队列只允许在一段进行插入数据操作,称为入队,在另一端进行删除数据操作,称为出队。我们可以把队列形象看作为排队。在最前面的进行出队,从最后面进行入队。 队列…...
机器学习PCA和LDA
主成分分析(PCA, Principal Component Analysis)和线性判别分析(LDA, Linear Discriminant Analysis)是两种常用的降维方法,它们虽然都用于数据降维,但核心思想和应用场景不同。 PCA(主成分分析…...
RocketMQ - 常见问题
RocketMQ常见问题 文章目录 RocketMQ常见问题一:消息幂等问题1:什么是消费幂等2:消息重复的场景分析2.1:发送时消息重复2.2:消费时消息重复2.3:Rebalance时消息重复 3:通用解决方案3.1ÿ…...
kafka消费能力压测:使用官方工具
背景 在之前的业务场景中,我们发现Kafka的实际消费能力远低于预期。尽管我们使用了kafka-go组件并进行了相关测试,测试情况见《kafka-go:性能测试》这篇文章。但并未能准确找出消费能力低下的原因。 我们曾怀疑这可能是由我的电脑网络带宽问题或Kafka部…...
基于Spring Boot的社区居民健康管理平台的设计与实现
目录 1 绪论 1.1 研究现状 1.2 研究意义 1.3 组织结构 2 技术介绍 2.1 平台开发工具和环境 2.2 Vue介绍 2.3 Spring Boot 2.4 MyBatis 2.5 环境搭建 3 系统需求分析 3.1 可行性分析 3.2 功能需求分析 3.3 系统用例图 3.4 系统功能图 4 系统设计 4.1 系统总体描…...
网络安全架构战略 网络安全体系结构
本节书摘来自异步社区《网络安全体系结构》一书中的第1章,第1.4节,作者【美】Sean Convery 1.4 一切皆为目标 网络安全体系结构 当前的大型网络存在着惊人的相互依赖性,作为一名网络安全设计师,对这一点必须心知肚明。Internet就…...
【Spring+MyBatis】_图书管理系统(中篇)
【SpringMyBatis】_图书管理系统(上篇)-CSDN博客文章浏览阅读654次,点赞4次,收藏7次。(1)当前页的内容records(类型为List);参数:userNameadmin&&pas…...
Python - 爬虫利器 - BeautifulSoup4常用 API
文章目录 前言BeautifulSoup4 简介主要特点:安装方式: 常用 API1. 创建 BeautifulSoup 对象2. 查找标签find(): 返回匹配的第一个元素find_all(): 返回所有匹配的元素列表select_one() & select(): CSS 选择器 3. 访问标签内容text 属性: 获取标签内纯文本get_t…...
宝塔面板开始ssl后,使用域名访问不了后台管理
宝塔面板后台开启ssl访问后,用的证书是其他第三方颁发的证书 再使用 域名/xxx 的形式:https://域名:xxx/xxx 访问后台,结果出现如下,不管使用 http 还是 https 的路径访问都进不后台管理 这个时候可以使用 https://ip/xxx 的方式来…...
大一计算机的自学总结:前缀树(字典树、Trie树)
前言 前缀树,又称字典树,Trie树,是一种方便查找前缀信息的数据结构。 一、字典树的实现 1.类描述实现 #include <bits/stdc.h> using namespace std;class TrieNode { public:int pass0;int end0;TrieNode* nexts[26]{NULL}; };Tri…...
docker 安装的open-webui链接ollama出现网络错误
# 故事背景 部署完ollama以后,使用谷歌浏览器的插件Page Assist - 本地 AI 模型的 Web UI 可以比较流畅的使用DeepSeek,但是只局限于个人使用,想分享给更多的小伙伴使用,于是打算使用open-webui 来管理用户,经官网推荐…...
未来游戏:当人工智能重构虚拟世界的底层逻辑
未来游戏:当人工智能重构虚拟世界的底层逻辑 在《赛博朋克2077》夜之城的霓虹灯下,玩家或许已经注意到酒吧里NPC开始出现微表情变化;在《艾尔登法环》的开放世界中,敌人的战术包抄逐渐显露出类人智慧。这些细节预示着游戏产业正站…...
Redis集群主从切换源码解读
一切的开始 打开Redis5.0.5的源码中server.c,找到如下代码,这里运行了一个定时任务,每隔100毫秒执行一次。 /* Run the Redis Cluster cron. *//** 每隔100毫秒执行一次* 要求开启集群模式*/run_with_period(100) {if (server.cluster_enabl…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
uniapp获取当前位置和经纬度信息
1.1. 获取当前位置和经纬度信息(需要配置高的SDK) 调用uni-app官方API中的uni.chooseLocation(),即打开地图选择位置。 <button click"getAddress">获取定位</button> const getAddress () > {uni.chooseLocatio…...
