引言

为什么要学习这个主题?

在上一篇文章中,我们了解了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上都能运行
               (但性能、行为细节可能不同)

关键点

  1. 规范保证兼容性:同一份.class文件可以在所有符合规范的JVM上运行
  2. 实现决定性能:不同JVM的GC算法、JIT优化策略不同,性能差异很大
  3. 实现可以扩展: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 性能对比表

特性HotSpotOpenJ9GraalVM
启动速度中等极快(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规范?

原因

  1. 保证兼容性:同一份字节码在所有JVM上都能运行
  2. 鼓励创新:不同厂商可以在规范范围内优化性能
  3. 平台无关性:规范定义了跨平台的标准

类比

  • 就像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启动快、内存小
ServerlessGraalVM 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 → 多元化时代(各有特色)

总结

核心要点回顾

  1. 虚拟机的分类

    • 系统虚拟机:模拟完整计算机(VMware)
    • 进程虚拟机:模拟程序执行环境(JVM)
  2. JVM规范 vs JVM实现

    • 规范:定义标准、保证兼容性
    • 实现:具体产品、性能有差异
  3. 主流JVM实现

    • HotSpot:市场主流,成熟稳定
    • OpenJ9:启动快,内存小
    • GraalVM:多语言,Native Image
  4. 选择建议

    • 通用场景:HotSpot(OpenJDK)
    • 云原生:OpenJ9
    • Serverless:GraalVM

思考题

  1. 为什么说"JVM是Java跨平台的关键"?规范和实现分别起什么作用?
  2. 如果你的应用需要在Docker容器中运行,应该选择哪个JVM?为什么?
  3. GraalVM的Native Image能编译成本地可执行文件,那还算是"Java虚拟机"吗?

下一篇预告

下一篇《JVM架构全景图:五大核心组件详解》,我们将深入探讨:

  • JVM的内部结构
  • 类加载器、运行时数据区、执行引擎等核心组件
  • 各组件如何协作运行Java程序
  • JVM的完整生命周期

参考资料


欢迎在评论区分享你对不同JVM的使用经验!