JVM 知识体系概览
什么是 JVM?
JVM(Java Virtual Machine,Java 虚拟机) 是 Java 程序的运行环境——它不是一台真正的物理机器,而是一个运行在操作系统之上的软件虚拟计算机。Java 代码编译后生成的字节码(.class 文件),就运行在 JVM 上。
JVM 做了三件核心的事情:
- 加载字节码——通过类加载器(ClassLoader)将
.class文件加载到内存 - 解释/编译执行——将字节码转换为机器指令运行(JIT 编译器会将热点代码编译为本地代码提升性能)
- 自动内存管理——通过垃圾回收器(GC)自动释放不再使用的对象内存
JVM 相当于 Java 的"浏览器"——理解 JVM 就像前端理解浏览器渲染原理和 V8 引擎一样重要。线上 OOM(内存溢出)、频繁 GC 导致卡顿、类加载冲突等问题,都需要 JVM 知识来排查。
JVM 运行时内存结构
| 区域 | 线程 | 存储内容 | 异常 |
|---|---|---|---|
| 程序计数器 | 私有 | 当前线程执行的字节码行号 | 不会 OOM |
| 虚拟机栈 | 私有 | 每个方法的栈帧(局部变量、操作数栈) | StackOverflowError |
| 本地方法栈 | 私有 | Native 方法调用 | StackOverflowError |
| 堆 | 共享 | 所有对象实例 | OutOfMemoryError |
| 方法区/元空间 | 共享 | 类信息、常量、静态变量 | OutOfMemoryError |
堆(Heap) 是 JVM 中最大的一块内存区域,几乎所有对象都在堆上分配。堆又分为新生代(Young Generation)和老年代(Old Generation),新创建的对象先放新生代,经过多次 GC 仍存活的对象晋升到老年代。
核心知识点
垃圾回收(GC)——自动的"内存清洁工"
Java 不需要手动 free() 释放内存,JVM 通过垃圾回收器(Garbage Collector) 自动回收不再使用的对象。
如何判断对象"已死"?
引用计数法:给对象加计数器,有引用 +1,引用失效 -1,为 0 则回收。缺点:无法解决循环引用- 可达性分析(Java 采用):从 GC Roots(栈中引用、静态变量、常量等)出发,能到达的对象是存活的,不可达的就是垃圾
GC 算法:
| 算法 | 原理 | 优缺点 |
|---|---|---|
| 标记-清除 | 标记存活对象,清除未标记的 | 简单但会产生内存碎片 |
| 标记-复制 | 将存活对象复制到另一半空间 | 无碎片但浪费一半空间(新生代用) |
| 标记-整理 | 将存活对象移到一端,清除边界外的 | 无碎片但移动成本高(老年代用) |
主流垃圾收集器:
| 收集器 | 算法 | 特点 | 适用场景 |
|---|---|---|---|
| Serial | 复制/整理 | 单线程,STW | 客户端/小内存 |
| Parallel | 复制/整理 | 多线程,追求吞吐量 | 后台任务 |
| CMS | 标记-清除 | 并发标记,低停顿 | Web 应用(已废弃) |
| G1 | 分区收集 | 可控停顿时间 | 大内存,JDK 9+ 默认 |
| ZGC | 染色指针 | 停顿 < 10ms | 超大内存,低延迟 |
类加载机制——.class 文件如何变成可执行的类
类加载分为五个阶段:加载 → 验证 → 准备 → 解析 → 初始化。
双亲委派模型是类加载的核心机制——当一个类加载器收到加载请求时,它不会自己去加载,而是先委托给父加载器,父加载器也向上委托,直到顶层的 Bootstrap ClassLoader。只有父加载器找不到时,子加载器才自己加载。
这样做的好处是保证核心类库的唯一性——无论谁加载 java.lang.String,最终都是由 Bootstrap ClassLoader 加载,防止有人自定义一个 String 类替换掉系统的。
JVM 调优——让 Java 应用"跑得更快"
JVM 调优的核心是通过调整 JVM 参数优化内存分配和 GC 行为:
# 常见 JVM 参数
-Xms512m # 堆最小内存
-Xmx2g # 堆最大内存
-Xmn512m # 新生代大小
-XX:+UseG1GC # 使用 G1 收集器
-XX:MaxGCPauseMillis=200 # 目标最大 GC 停顿
OOM 排查——线上最常见的"事故"
OutOfMemoryError 是线上最常见的 JVM 故障。常见类型:
- Java heap space:堆内存不足(大对象、内存泄漏)
- Metaspace:元空间不足(动态生成大量类)
- Unable to create new native thread:线程数超限
排查工具:jps(查进程)→ jmap -dump(导出堆转储)→ MAT(Eclipse Memory Analyzer Tool)分析。
学习建议
- 内存结构 → 理解 JVM 各区域的作用
- 垃圾回收 → GC 算法 + 收集器对比
- 类加载 → 双亲委派 + 打破双亲委派
- JVM 调优 → 参数配置 + GC 日志分析
- OOM 排查 → 线上故障排查实战