引言
为什么要学习这个主题?
在上一篇文章中,我们了解了Java程序的运行流程,知道了JVM在其中扮演着"翻译官"的角色。但你是否想过:
- JVM到底是一个软件?还是一个标准?
- 为什么Oracle的JDK和OpenJDK的行为基本一致?
- HotSpot、OpenJ9、GraalVM这些名字都是什么?有什么区别?
理解JVM的本质,是掌握Java技术栈的关键。就像理解"什么是HTTP"比单纯会用浏览器更重要一样。
你将学到什么?
- ✅ 虚拟机的本质与分类
- ✅ JVM规范与JVM实现的区别
- ✅ 主流JVM实现的特点与选择
- ✅ 如何查看和切换JVM
一、什么是虚拟机?
1.1 虚拟机的定义
虚拟机(Virtual Machine):通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。
简单来说:用软件模拟硬件。
1.2 虚拟机的分类
系统虚拟机(System VM)
代表:VMware、VirtualBox、Parallels Desktop
特点:
- 模拟完整的计算机系统
- 可以运行完整的操作系统
- 提供硬件虚拟化(CPU、内存、硬盘、网卡等)
使用场景:
物理机(Windows)
↓
VMware 虚拟机
↓
虚拟Linux系统(完整的操作系统)
进程虚拟机(Process VM)
代表:JVM、Python解释器、.NET CLR
特点:
- 只模拟程序运行环境
- 不需要完整的操作系统
- 为单个进程提供跨平台的执行环境
使用场景:
物理机(任何OS)
↓
JVM进程虚拟机
↓
Java程序(字节码)
1.3 JVM属于哪一类?
JVM是进程虚拟机(Process VM)
- 不模拟硬件
- 只提供字节码的执行环境
- 每个Java程序运行在一个JVM进程中
关键理解:
系统虚拟机 = 虚拟计算机(有CPU、内存、硬盘)
进程虚拟机 = 虚拟执行环境(只能运行特定程序)
二、JVM的本质:规范 vs 实现
2.1 JVM规范(JVM Specification)
定义:Oracle官方发布的一份技术文档,详细定义了JVM应该做什么、怎么做。
核心内容:
- class文件格式
- 字节码指令集
- 运行时数据区域
- 垃圾收集机制(但不规定具体算法)
- 异常处理
官方文档:The Java Virtual Machine Specification
类比理解:
JVM规范 = 蓝图、标准、接口
就像:
- HTTP规范定义了浏览器和服务器如何通信
- SQL标准定义了数据库查询语言的语法
但规范本身不能运行,需要有人按照规范去实现。
2.2 JVM实现(JVM Implementation)
定义:按照JVM规范开发的具体软件产品。
常见JVM实现:
- HotSpot:Oracle官方JVM(最流行)
- OpenJ9:IBM开源的JVM(原Eclipse OpenJ9)
- GraalVM:Oracle新一代多语言虚拟机
- Zing:Azul公司的商业JVM(低延迟)
- Dalvik/ART:Android平台的JVM
类比理解:
JVM实现 = 按照蓝图建造的房子
就像:
- Chrome、Firefox、Safari都是HTTP规范的实现(浏览器)
- MySQL、PostgreSQL、Oracle都是SQL标准的实现(数据库)
虽然都遵循同一个规范,但实现细节、性能、特性会有差异。
2.3 规范与实现的关系
┌─────────────────────────────────┐
│ JVM规范(Specification) │
│ - class文件格式 │
│ - 字节码指令集 │
│ - 运行时数据区 │
│ - 垃圾回收机制定义 │
└────────────┬────────────────────┘
│ 遵循
┌───────┴────────┐
↓ ↓
┌──────────┐ ┌──────────┐
│ HotSpot │ │ OpenJ9 │ ... 更多实现
│ JVM │ │ JVM │
│ │ │ │
│ Oracle │ │ IBM │
└──────────┘ └──────────┘
同一份字节码 → 在不同JVM上都能运行
(但性能、行为细节可能不同)
关键点:
- 规范保证兼容性:同一份
.class文件可以在所有符合规范的JVM上运行 - 实现决定性能:不同JVM的GC算法、JIT优化策略不同,性能差异很大
- 实现可以扩展:JVM可以在规范之外提供额外功能(如工具、监控)
三、主流JVM实现对比
3.1 HotSpot JVM
开发者:Sun Microsystems(现在Oracle)
特点:
- 市场占有率最高(超过90%)
- 成熟稳定:经过20多年的优化
- 强大的JIT编译器:C1(客户端编译器)+ C2(服务端编译器)
- 多种GC算法:Serial、Parallel、CMS、G1、ZGC
适用场景:
- 通用应用开发(首选)
- 需要稳定性的生产环境
- 有丰富生态工具支持
版本来源:
Oracle JDK:商业版本(需要授权)
OpenJDK:开源版本(免费,社区维护)
Adoptium(前AdoptOpenJDK):预构建的OpenJDK版本
Amazon Corretto:AWS提供的OpenJDK发行版
3.2 OpenJ9 JVM
开发者:IBM(现在Eclipse基金会)
特点:
- 启动速度快:比HotSpot快30-40%
- 内存占用小:适合容器化环境
- 快速预热:Ahead-of-Time (AOT) 编译
- 独特的GC算法:Balanced GC、Metronome GC
适用场景:
- 云原生应用(Kubernetes)
- 短生命周期服务
- 内存受限环境
获取方式:
Eclipse OpenJ9:https://www.eclipse.org/openj9/
IBM Semeru Runtimes:IBM提供的OpenJ9发行版
3.3 GraalVM
开发者:Oracle Labs
特点:
- 多语言支持:Java、JavaScript、Python、Ruby等
- Native Image:编译成本地可执行文件(无需JVM)
- 极致启动速度:毫秒级启动
- 高级JIT编译器:Graal Compiler
适用场景:
- Serverless函数(AWS Lambda)
- 微服务(快速启动)
- 多语言混合应用
版本:
GraalVM Community Edition:免费开源
GraalVM Enterprise Edition:商业版(性能更优)
3.4 性能对比表
| 特性 | HotSpot | OpenJ9 | GraalVM |
|---|---|---|---|
| 启动速度 | 中等 | 快 | 极快(Native Image) |
| 预热时间 | 中等 | 快 | 快 |
| 峰值性能 | 优秀 | 良好 | 优秀 |
| 内存占用 | 中等 | 小 | 小(Native Image) |
| 生态成熟度 | 最成熟 | 成熟 | 快速发展 |
| 学习曲线 | 平缓 | 中等 | 陡峭 |
| 适用场景 | 通用 | 云原生 | 云原生/Serverless |
四、实战:查看和切换JVM
4.1 查看当前JVM版本
# 查看Java版本
java -version
HotSpot输出示例:
openjdk version "17.0.9" 2023-10-17
OpenJDK Runtime Environment (build 17.0.9+9)
OpenJDK 64-Bit Server VM (build 17.0.9+9, mixed mode)
↑
这里显示JVM类型
OpenJ9输出示例:
openjdk version "17.0.9" 2023-10-17
OpenJDK Runtime Environment (build openj9-0.41.0)
Eclipse OpenJ9 VM (build openj9-0.41.0, JRE 17)
↑
显示OpenJ9
4.2 使用不同的JVM运行程序
示例程序:
// JVMInfo.java
public class JVMInfo {
public static void main(String[] args) {
System.out.println("JVM名称: " +
System.getProperty("java.vm.name"));
System.out.println("JVM版本: " +
System.getProperty("java.vm.version"));
System.out.println("JVM供应商: " +
System.getProperty("java.vm.vendor"));
// 内存信息
Runtime runtime = Runtime.getRuntime();
long maxMemory = runtime.maxMemory() / 1024 / 1024;
long totalMemory = runtime.totalMemory() / 1024 / 1024;
System.out.println("最大内存: " + maxMemory + "MB");
System.out.println("已分配内存: " + totalMemory + "MB");
}
}
编译运行:
# 编译
javac JVMInfo.java
# HotSpot运行
java JVMInfo
# 如果安装了OpenJ9,切换到OpenJ9运行
# (需要先安装OpenJ9版本的JDK)
/path/to/openj9-jdk/bin/java JVMInfo
输出对比:
HotSpot:
JVM名称: OpenJDK 64-Bit Server VM
JVM版本: 17.0.9+9
JVM供应商: Oracle Corporation
最大内存: 4096MB
已分配内存: 256MB
OpenJ9:
JVM名称: Eclipse OpenJ9 VM
JVM版本: openj9-0.41.0
JVM供应商: Eclipse OpenJ9
最大内存: 2048MB # 默认内存更小
已分配内存: 128MB
4.3 安装和管理多个JVM
使用SDKMAN!(推荐):
# 安装SDKMAN!
curl -s "https://get.sdkman.io" | bash
# 列出可用的Java版本
sdk list java
# 安装不同的JVM
sdk install java 17.0.9-tem # Adoptium (HotSpot)
sdk install java 17.0.9-sem # Semeru (OpenJ9)
sdk install java 17.0.9-graal # GraalVM
# 切换默认JVM
sdk use java 17.0.9-sem
# 查看当前版本
java -version
五、常见问题与疑问
❓ 问题1:为什么需要JVM规范?
原因:
- 保证兼容性:同一份字节码在所有JVM上都能运行
- 鼓励创新:不同厂商可以在规范范围内优化性能
- 平台无关性:规范定义了跨平台的标准
类比:
- 就像USB接口标准,让不同厂商的设备都能互相兼容
- 如果没有规范,每个JVM都自己定义字节码格式,Java就无法跨平台了
❓ 问题2:HotSpot和OpenJDK是什么关系?
关系:
OpenJDK = 开源Java开发套件(包含JVM、类库、工具)
↓
HotSpot = OpenJDK中的JVM实现(核心组件)
说明:
- OpenJDK是完整的Java开发套件(JDK)
- HotSpot是OpenJDK内部使用的JVM
- 下载OpenJDK时,默认就是使用HotSpot JVM
❓ 问题3:应该选择哪个JVM?
推荐策略:
| 场景 | 推荐JVM | 理由 |
|---|---|---|
| 通用开发 | HotSpot (OpenJDK) | 生态成熟、资料丰富、稳定 |
| 云原生/容器 | OpenJ9 | 启动快、内存小 |
| Serverless | GraalVM Native Image | 毫秒级启动、无需JVM |
| 遗留系统 | HotSpot | 兼容性最好 |
| 低延迟应用 | Azul Zing | 专业GC算法 |
初学者建议:先学习HotSpot,熟悉后再探索其他JVM。
❓ 问题4:JVM版本和Java版本是什么关系?
关系:
Java 8 → HotSpot 25.x
Java 11 → HotSpot 11.x
Java 17 → HotSpot 17.x
Java版本号 ≈ JVM版本号(但不完全等同)
说明:
- Java版本指语言特性和标准库版本
- JVM版本指虚拟机的版本
- 通常一起升级,但JVM版本号规则更复杂
六、深入理解:为什么有这么多JVM实现?
6.1 不同实现的优化方向不同
HotSpot:
↓
优化目标:峰值性能
策略:分层编译、强大的C2编译器
适合:长时间运行的服务
OpenJ9:
↓
优化目标:启动速度、内存占用
策略:AOT编译、共享类缓存
适合:短生命周期、容器化
GraalVM:
↓
优化目标:极致启动、多语言
策略:Native Image、提前编译
适合:Serverless、微服务
6.2 JVM实现的演进历史
1995 → Sun Classic VM(最早的JVM)
↓
1999 → HotSpot VM(Sun收购,成为主流)
↓
2006 → OpenJDK发布(HotSpot开源)
↓
2017 → OpenJ9开源(IBM贡献给Eclipse)
↓
2019 → GraalVM正式发布(Oracle新一代)
↓
2024 → 多元化时代(各有特色)
总结
核心要点回顾
虚拟机的分类
- 系统虚拟机:模拟完整计算机(VMware)
- 进程虚拟机:模拟程序执行环境(JVM)
JVM规范 vs JVM实现
- 规范:定义标准、保证兼容性
- 实现:具体产品、性能有差异
主流JVM实现
- HotSpot:市场主流,成熟稳定
- OpenJ9:启动快,内存小
- GraalVM:多语言,Native Image
选择建议
- 通用场景:HotSpot(OpenJDK)
- 云原生:OpenJ9
- Serverless:GraalVM
思考题
- 为什么说"JVM是Java跨平台的关键"?规范和实现分别起什么作用?
- 如果你的应用需要在Docker容器中运行,应该选择哪个JVM?为什么?
- GraalVM的Native Image能编译成本地可执行文件,那还算是"Java虚拟机"吗?
下一篇预告
下一篇《JVM架构全景图:五大核心组件详解》,我们将深入探讨:
- JVM的内部结构
- 类加载器、运行时数据区、执行引擎等核心组件
- 各组件如何协作运行Java程序
- JVM的完整生命周期
参考资料
- The Java Virtual Machine Specification (Java SE 17)
- HotSpot Virtual Machine
- Eclipse OpenJ9
- GraalVM
- 《深入理解Java虚拟机(第3版)》- 周志明,第1章
欢迎在评论区分享你对不同JVM的使用经验!