什么是 JVM?
JVM(Java Virtual Machine)是 Java 虚拟机的缩写,它是一套规范,定义了如何在硬件上仿真模拟计算机功能。你可以把它理解为一个虚构的计算机,通过在实际机器上运行字节码指令集、寄存器、栈、堆和方法域来实现计算。
JVM 的核心价值在于屏蔽了操作系统平台的差异。Java 程序只需编译成在 JVM 上运行的目标代码(即字节码),就能在不同平台上不加修改地运行。当 JVM 执行字节码时,它会将其解释或即时编译为具体平台上的机器指令。这就是 Java 实现'一次编译,到处运行'的关键所在。
JRE、JDK 与 JVM 的关系
这三个概念经常被混淆,其实它们有明确的层级关系:
- JRE (Java Runtime Environment):Java 运行环境。普通用户只需要运行已开发好的 Java 程序,安装 JRE 即可。它是 Java 程序运行的基础平台。
- JDK (Java Development Kit):Java 开发工具包。开发者用来编译和调试 Java 程序的工具集合。JDK 包含 JRE,因为 JDK 中的工具本身也是 Java 程序,需要 JRE 支持才能运行。所以安装 JDK 时会自动包含 JRE 目录。
- JVM:JRE 的一部分,是 JRE 中最核心的组件。它是一个具有完善硬件架构(如处理器、堆栈、寄存器等)的抽象计算机,负责执行字节码并实现跨平台特性。
JVM 执行原理与生命周期
JVM 位于 Java 编译器和操作系统之间,充当虚拟处理器的角色。Java 源文件被编译器翻译成 JVM 能理解的字节码,再由 JVM 翻译成特定平台的机器码执行。
执行程序的过程
JVM 启动后,主要经历以下几个阶段:
- 加载:将
.class文件载入内存。 - 验证:确保字节码符合规范,不会危害系统安全。
- 准备:为静态变量分配内存并设置默认值。
- 解析:将常量池内的符号引用替换为直接引用。
- 初始化:执行类构造器
<clinit>方法。
JVM 作为一个进程运行,拥有自己的生命周期。操作系统通过 java.exe 装入 JVM,完成环境配置、装载 JVM.dll、初始化 JNI 接口实例,最终调用该实例处理类加载。
生命周期状态
- 启动:当运行一个包含
public static void main(String[] args)方法的类时,JVM 实例诞生。 - 运行:
main()方法是初始线程的起点,其他线程由此启动。JVM 内部维护守护线程和非守护线程,只有非守护线程全部终止,JVM 才会退出。 - 消亡:除非安全管理器允许或通过
System.exit()强制退出,否则 JVM 会在所有非守护线程结束后自然结束。
JVM 体系结构
JVM 的整体架构主要由三部分组成:
- 类装载器 (ClassLoader):负责加载
.class文件到内存中。 - 执行引擎:负责执行字节码指令或本地方法。
- 运行时数据区:包括方法区、堆、Java 栈、PC 寄存器和本地方法栈。
运行时数据区详解
这是 JVM 内存管理的核心,理解各区域的作用对性能调优至关重要。
PC 寄存器
每个线程都有独立的 PC 寄存器,用于存储当前线程下一条要执行的 JVM 指令地址。如果当前执行的是 native 方法,则 PC 寄存器不存储信息。
JVM 栈
线程私有的内存区域,随着线程创建而创建。栈帧中存放局部变量表(基本类型变量)、操作数栈、动态链接和方法出口等信息。对于非基本类型的对象,栈中仅保存指向堆中对象的引用地址。


