虚拟机与 Java 虚拟机介绍
什么是虚拟机
虚拟机(Virtual Machine,VM)这个概念,拆开来看很简单:虚拟的机器,即通过软件模拟出来的、具有完整硬件系统功能的、运行在一个隔离环境中的计算机系统。
你可能用过这些虚拟机:
- VMware / VirtualBox:在一台物理机上虚拟出多台「电脑」,每台「电脑」可以运行独立的操作系统
- Docker:轻量级的「虚拟机」,但它其实更准确的说法是「容器」,共享宿主机内核
- JVM:不模拟硬件,而是模拟一个虚拟的 CPU 和内存系统,专门用来运行字节码
虚拟机的分类
虚拟机大体分为两类,理解它们的区别有助于理解 JVM 的定位:
| 类型 | 代表 | 特点 |
|---|---|---|
| 系统虚拟机 | VMware、VirtualBox、QEMU | 模拟完整的硬件平台(CPU、内存、磁盘、网络),可以运行完整的操作系统 |
| 应用虚拟机 | JVM、.NET CLR、Python PVM | 不模拟硬件,只模拟 CPU 指令集,为特定语言的程序提供运行时环境 |
JVM 属于应用虚拟机(也称为语言虚拟机)。它的设计目标不是让你在虚拟机里装 Windows,而是让字节码能够在任何操作系统上运行。
Java 虚拟机的定义
Java 虚拟机是一个抽象的计算机规范,由《Java 虚拟机规范》(Java Virtual Machine Specification)明确定义。
这个规范定义了什么?主要是以下几方面:
- 指令集:JVM 支持哪些指令,每条指令做什么
- 数据类型:JVM 认识哪些数据类型(int、long、float、double、reference……)
- 运行时数据区:内存怎么划分,每个区域干什么用
- Class 文件格式:字节码文件的二进制结构
- 类加载机制:字节码怎么被加载进 JVM
- 异常与错误处理:字节码执行过程中的异常怎么处理
- 指令执行模型:基于栈的指令执行方式
关键点:JVM 是一份规范,不是具体的实现。Oracle 的 HotSpot 是这份规范最著名的实现,但不是唯一实现。
JVM 的核心特性
1. 基于栈的虚拟机
JVM 和大多数物理 CPU(x86、ARM)不同。大多数物理 CPU 是基于寄存器的,而 JVM 是基于栈的。
基于栈的虚拟机有两个特点:
- 操作数通过栈传递:不像寄存器机器那样指令直接操作寄存器,所有运算都在操作数栈上进行
- 指令更简洁:因为不需要指定操作数来源,指令本身更短,更容易跨平台
// 计算 1 + 2
iload_0 // 从局部变量槽0加载值到栈顶
iconst_2 // 常量2入栈
iadd // 弹出栈顶两个值相加,结果入栈2. 自动内存管理
JVM 替程序员做了两件 C/C++ 程序员必须手动做的事情:
- 内存分配:用
new创建对象时,JVM 自动在堆上分配内存 - 垃圾回收:对象不再使用时,JVM 自动回收其占用的内存
这是 Java 最核心的价值之一,也是 JVM 最重要的子系统之一。
3. 平台无关性
《Java 虚拟机规范》保证了字节码格式的一致性。只要 JVM 实现符合规范,.class 文件就能正确加载和执行。
这意味着字节码是 Java 的「汇编语言」,而 JVM 是这个汇编语言的「CPU」。
4. 安全性
JVM 有一套严格的安全检查机制:
- 字节码验证器:确保加载的字节码不会破坏 JVM 的完整性(比如访问越界、伪造指针)
- 安全管理器(SecurityManager):可以细粒度地控制代码对系统资源的访问
- 类型安全:JVM 的类型系统不允许把一个整数当指针使用
这些机制让不可信的代码(如 Applet)在浏览器中安全运行成为可能。
5. 混合执行模式
JVM 不是纯解释执行的,也不是纯编译执行的,而是两者结合:
- 解释执行:字节码被逐条解释成机器码执行,启动快
- JIT 编译:热点代码被编译器编译成本地机器码执行,执行快
JIT 编译器会在运行时收集各种统计数据(分支频率、对象分配频率等),据此做激进优化。这种基于运行时信息的优化,是 JVM 性能超越纯解释器的关键。
JVM 不是一个完整的操作系统
JVM 运行在宿主操作系统之上,依赖操作系统提供的服务:
┌──────────────────────────────────────┐
│ Java 应用程序 │
├──────────────────────────────────────┤
│ Java 核心类库(rt.jar) │
├──────────────────────────────────────┤
│ JVM 运行时 │
│ (类加载器 / 执行引擎 / 内存管理 / GC) │
├──────────────────────────────────────┤
│ 操作系统 │
│ (Linux / Windows / macOS) │
├──────────────────────────────────────┤
│ 硬件 │
│ (x86 / ARM / RISC-V) │
└──────────────────────────────────────┘JVM 向上为 Java 程序提供运行时环境,向下调用操作系统的 API。这种分层设计让 Java 保持跨平台能力,同时又能利用各操作系统的底层能力。
JVM 的具体实现
规范是一回事,实现是另一回事。目前主流的 JVM 实现有:
| 实现 | 厂商 | 特点 |
|---|---|---|
| HotSpot | Oracle / OpenJDK | 最流行,JDK 默认,JIT 优化成熟 |
| JRockit | Oracle(已停止) | 曾以高性能著称,后被 HotSpot 合并 |
| IBM J9 | IBM | 企业级,J9 在 IBM 商业产品中使用广泛 |
| GraalVM | Oracle Labs | 新一代 VM,支持 AOT 编译和 polyglot |
| Azul Zing | Azul | 超低停顿 GC(PGC/C4) |
本教程的内容以 HotSpot 为主,因为它是最普遍使用的 JVM 实现。
本节小结
JVM 是一个规范,它定义了一个虚拟计算机应该怎么运行字节码。它不是硬件虚拟机,而是语言虚拟机——为 Java(以及其他语言)提供运行时环境。
它的核心特性:基于栈的指令集、自动内存管理、平台无关、安全可控、解释+JIT 混合执行。
下一节,我们来看看 JVM 的位置与整体结构,从宏观上认识 JVM 的各个组成部分。
