Java 虚拟机(JVM)
一、JVM 的核心功能
跨平台执行
Java 源代码(.java
)编译为字节码(.class
),JVM 在运行时将字节码解释/编译成具体平台的机器指令,实现"一次编写,到处运行"。
示例: Windows 和 Linux 的 JVM 实现不同,但执行相同的字节码。内存管理
自动管理内存分配与回收,通过垃圾回收(GC)机制释放无用对象占用的堆内存。运行时环境
提供线程管理、异常处理、安全检查等运行时支持。
二、JVM 核心组件
根据运行时数据区域划分:
组件 | 作用 | 线程安全 |
---|---|---|
程序计数器 | 存储当前线程执行的字节码指令地址 | 线程私有 |
Java虚拟机栈 | 存储栈帧(局部变量表、操作数栈、方法出口等) | 线程私有 |
本地方法栈 | 支持 Native 方法(如 C/C++ 代码)的执行 | 线程私有 |
堆内存 | 存储所有对象实例和数组(GC 主要区域) | 线程共享 |
方法区 | 存储类信息、常量、静态变量(JDK8+ 由元空间实现) | 线程共享 |
运行时常量池 | 存储类文件中的常量(如字符串字面量) | 线程共享 |
三、JVM 工作流程
类加载
- 加载:通过类加载器(ClassLoader)将
.class
文件读入内存 - 链接:
- 验证:检查字节码合法性
- 准备:为静态变量分配内存
- 解析:符号引用转直接引用
- 初始化:执行静态代码块和静态变量赋值
- 加载:通过类加载器(ClassLoader)将
字节码执行
- 解释执行:逐条解释字节码(启动快,执行慢)
- 即时编译(JIT):将热点代码编译为本地机器码(执行快,编译耗时)
公式:$ \text{执行效率} = \alpha \cdot \text{JIT编译} + \beta \cdot \text{解释执行} $
垃圾回收(GC)
- 标记阶段:从 GC Roots 遍历对象引用链,标记存活对象
- 回收阶段:
- 复制算法(新生代)
- 标记-整理(老年代)
- 常用 GC 算法对比:
算法 适用区域 特点 停顿时间 Serial GC 新生代 单线程复制 高 G1 GC 全堆 分Region收集,可预测停顿 中 ZGC 全堆 并发标记整理 <10ms
四、JVM 架构示例
public class JVMArchDemo {
static final String CONSTANT = "常量池示例"; // 进入运行时常量池
static int staticVar = 1; // 方法区存储
public static void main(String[] args) {
int stackVar = 10; // 栈帧存储
Object obj = new Object(); // 对象在堆分配
System.out.println(obj.hashCode());
}
}
五、关键优化技术
- 分层编译(Tiered Compilation)
- 混合使用解释器、C1编译器(轻量优化)、C2编译器(深度优化)
- 逃逸分析
将未逃逸对象分配在栈上,减少GC压力:
对象分配成本栈≪对象分配成本堆 \text{对象分配成本}_{栈} \ll \text{对象分配成本}_{堆} 对象分配成本栈≪对象分配成本堆 - 元空间(Metaspace)替代永久代
JDK8+ 使用本地内存存储类元数据,避免java.lang.OutOfMemoryError: PermGen space
。