JVM 面试题在网上刷到过很多版本,但真正能一口气覆盖类加载、内存模型、GC 原理、三色标记、性能调优,还顺带把 MySQL 面试题一起带的资料很少。这次我们直接把这套“JVM 面试 45 问”的知识体系拆开:先看它包含哪些板块,再看每个板块怎么学、怎么验证、怎么答,最后给出一套能直接执行的复习方案。
先说结论:这套内容不是让你把 45 道题的答案背下来,而是帮你把“类加载 → JVM 虚拟机内存 → GC 原理 → 三色标记 → 性能调优 → MySQL 面试题”串成一张知识网。面试官现在问 JVM 很少只问单个概念,而是连环追问,比如“类加载过程讲一下”“那双亲委派为什么能防止类重复加载”“G1 的 Region 怎么回收”“三色标记漏标怎么解决”。如果你的知识是零散记忆,很容易在第二层、第三层追问里卡住。
本文会先给这套内容的核心能力速览,再按板块拆解学习路径,提供可复制的命令、参数和实验方式,最后给出自查清单和常见学习误区。适合准备 Java 后端面试、想系统重建 JVM 知识体系、以及需要同时复习 MySQL 高频题的读者。
1. JVM 面试 45 问核心能力速览
这套面试题复习体系的核心能力,可以先用一张表看清:
| 能力项 | 说明 |
|---|---|
| 知识板块 | 类加载机制、JVM 内存模型、GC 原理、三色标记、JVM 性能调优、MySQL 面试题 |
| 覆盖场景 | Java 后端面试、高并发与性能优化岗位、JVM 调优实际排查 |
| 问题数量参考 | 45 问左右,按板块分布,重点在 JVM 内存与 GC |
| 适合人群 | 1 到 5 年 Java 后端开发者、跳槽面试者、JVM 知识不系统的学习者 |
| 是否需要真实 JVM 环境 | 需要,建议本地安装 JDK 8 和 JDK 17 各一套 |
| 是否需要 MySQL | 建议准备一个本地 MySQL,用于验证索引、事务、锁相关面试题 |
| 学习方式 | 概念梳理 + 面试答题模板 + 命令行验证 + 故障实验 |
| 核心难点 | 三色标记与漏标问题、G1 回收流程、类加载双亲委派、GC 日志分析 |
| 资源需求 | 8G 内存机器即可,不需要特殊 GPU 或大型服务器 |
| 是否涉及 API / 批量任务 | 不涉及,这套内容重点是知识梳理与面试自测,不是工具平台 |
从材料看,这套复习内容把 JVM 和 MySQL 放在一起并不是拼凑。实际面试中,JVM 调优经常和数据库性能问题一起出现,比如线上 CPU 飙升、接口变慢,先看 Full GC 还是先看慢 SQL,这个排查顺序本身就是高频考点。
2. 适用人群与使用边界
2.1 适合谁
- 准备 Java 后端面试的人:需要把 JVM 内存、GC、类加载这些高频题整理成有逻辑的答案。
- 工作中遇到过内存溢出、CPU 飙升但不知道如何排查的人:这套内容里的性能调优部分能补上排查链路。
- 想系统复习 MySQL 面试题的人:索引失效、事务隔离级别、MVCC、锁机制这些经典问题,可以和 JVM 的并发、内存模型对照理解。
- 有 Java 基础但没系统学过 JVM 的人:45 问的价值在于把所有考点串起来,避免“知道每个概念、但答不完整一个流程”。
2.2 不适合谁
- 完全没写过 Java 代码的人:JVM 面试题默认你有 Java 语法基础,至少能看懂类和对象的基本概念。
- 只想背答案、不想理解原理的人:面试官现在普遍会打断背诵,追问“为什么”“如果参数改大一点会怎样”。
2.3 使用边界与合规提醒
面试题总结本质是知识梳理,不涉及任何敏感技术或违规操作。但在学习性能调优时要注意:所有 JVM 实验、内存溢出测试、死锁模拟,都在本地测试环境完成,不要拿生产环境直接复现。涉及 MySQL 实验同样如此,不要在他人数据库上执行锁表或删除操作。
3. 学习环境与前置条件
这套面试题复习不要求多高的机器配置,但环境准备会影响后续实验效果。建议按以下清单准备。
3.1 操作系统
Windows、macOS、Linux 都可以。优先选 Linux 或 macOS,因为 JVM 调优和故障排查的很多命令在 Unix 环境下更稳定,而且面试中问到线上排查时,面试官默认你熟悉 Linux 命令。
3.2 JDK 版本
建议同时安装 JDK 8 和 JDK 17。JDK 8 是很多公司生产环境的主流版本,默认使用 Parallel Scavenge + Parallel Old;JDK 17 默认使用 G1,是现在面试中频率逐渐上升的版本。
安装完成后先验证版本:
java -version # 期望输出类似: # java version "1.8.0_202" # Java(TM) SE Runtime Environment (build 1.8.0_202-b08) # Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)# 切换 JDK 17 后验证 java -version # 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)注意:如果本机安装了多个 JDK,需要配置JAVA_HOME和PATH,否则命令行会使用错误版本。面试中也有一个热词是“jre和jvm之间的关系”“jdk和jvm、jre的区别”,这属于 JDK 安装时的基础题,环境准备阶段顺手就能验证。
3.3 IDE 与工具
推荐使用 IntelliJ IDEA 社区版或 VS Code,至少需要一个能写 Java 文件的编辑器。不需要额外插件,JVM 实验本身通过命令行就能完成。
3.4 JVM 监控与排查工具
JDK 自带工具优先掌握,这些都是免费的,也是面试中经常被问到的:
| 工具 | 作用 | 常用命令 |
|---|---|---|
| jps | 查看 Java 进程 | jps -l |
| jstat | 查看类加载、GC、JIT 统计 | jstat -gc <pid> 1000 |
| jmap | 生成堆转储、查看堆信息 | jmap -heap <pid> |
| jstack | 查看线程栈 | jstack <pid> |
| jcmd | 综合诊断命令 | jcmd <pid> help |
3.5 MySQL 环境
如果要连着复习 MySQL 面试题,准备一个本地 MySQL 8.0 即可。安装时注意字符集和认证插件,MySQL 8.0 默认的caching_sha2_password会影响一些旧客户端连接,如果使用 Navicat 等工具连接失败,可以检查认证插件问题。
# 检查 MySQL 版本 mysql --version环境准备好之后,就可以按板块逐个突破了。
4. 类加载机制专题:从过程到双亲委派
类加载是 JVM 面试的第一个高频板块。面试官会从“类从加载到使用的完整过程”问起,然后延伸到双亲委派、类加载器分类、Tomcat 为什么需要破坏双亲委派。
4.1 类加载全过程
一个类从被加载到 JVM 到卸载,完整生命周期包括 7 个阶段:
加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载
面试时最容易搞混的是“准备”和“初始化”阶段。准备阶段为静态变量分配内存并设置零值,例如static int count = 10,在准备阶段 count 的值是 0,真正赋值为 10 发生在初始化阶段。这个细节几乎每年都会考。
验证阶段主要做四件事:文件格式验证、元数据验证、字节码验证、符号引用验证。准备阶段之后才进入解析阶段,将符号引用替换为直接引用。
初始化阶段会执行<clinit>()方法,触发时机包括 new、反射、调用静态方法、访问静态字段、初始化子类时先初始化父类等。
4.2 双亲委派模型
双亲委派的核心逻辑是:类加载器收到类加载请求后,先把请求委派给父加载器,父加载器无法完成时才由自己加载。
三个内置加载器:
- Bootstrap ClassLoader:加载
JAVA_HOME/lib目录下核心类,比如rt.jar。 - Platform ClassLoader / Extension ClassLoader:JDK 8 叫扩展类加载器,JDK 9 后改为平台类加载器,加载一些扩展库。
- Application ClassLoader:加载 classpath 下的类。
面试答题模板:
“双亲委派的作用主要有三点:第一,避免类被重复加载,父加载器加载过的类,子加载器不会再去加载;第二,保证 Java 核心类库的安全,比如你自定义一个java.lang.String,最终会被引导类加载器拦截,无法覆盖核心类;第三,保证类加载的层级关系一致,同一个类在同一个加载器下只被加载一次。”
接着面试官大概率会问“那为什么要破坏双亲委派”。典型场景是 Tomcat 的 Web 应用类加载器,每个应用需要隔离自己的依赖版本,所以打破了默认的父优先模式。SPI 机制如 JDBC 驱动加载也是破坏双亲委派的例子。
4.3 面试答题模板示例
可以把这个答题结构背下来:
先讲生命周期七个阶段 → 重点讲加载、验证、准备、初始化 → 再讲类加载器层级 → 最后补双亲委派的作用和破坏场景。
这样回答不仅完整,而且能引导面试官问你准备好的下一个点。
5. JVM 内存模型、GC 原理与三色标记
这是整套 45 问里分量最重的板块。字节、美团这类公司面试时,JVM 内存布局和 GC 流程能连续追问十分钟。
5.1 运行时数据区
JVM 运行时数据区分为线程共享和线程私有两类。
线程私有:
- 虚拟机栈:每个方法调用对应一个栈帧,栈帧里有局部变量表、操作数栈、动态链接、方法返回地址。
- 本地方法栈:为 native 方法服务。
- 程序计数器:记录当前线程执行的字节码行号。
线程共享:
- 堆:对象实例主要分配在这里,是 GC 的主要区域。
- 方法区:存储类元信息、常量、静态变量。JDK 8 之后改名为元空间,使用本地内存,不再受堆大小限制。
- 运行时常量池:JDK 8 后移到堆中。
这里有一个高频扩展题:什么是栈溢出、什么是堆溢出。
public class StackOverflowDemo { public static void main(String[] args) { recurse(0); } private static void recurse(int depth) { System.out.println("depth = " + depth); recurse(depth + 1); } }运行后会抛出java.lang.StackOverflowError,这就是虚拟机栈深度超限的结果。
5.2 对象创建流程
面试官问到“new 一个对象发生了什么”,不要只回答“分配一块内存”。完整流程是:
类加载检查 → 分配内存 → 初始化零值 → 设置对象头 → 执行<init>方法。
内存分配方式有两种:指针碰撞和空闲列表。是否使用指针碰撞取决于堆内存是否规整,而堆是否规整取决于垃圾回收器是否带压缩整理功能,比如 Serial、ParNew 带压缩,CMS 则不压缩。
还要掌握对象在堆中的内存布局:对象头、实例数据、对齐填充。对象头里包含 Mark Word 和类型指针,Mark Word 里存了锁状态、hashCode、GC 分代年龄等信息。
5.3 垃圾回收算法
JVM 垃圾回收涉及三个经典算法:
- 标记-清除
- 标记-复制
- 标记-整理
标记-清除会产生内存碎片,标记-复制适合存活率低的年轻代,标记-整理适合存活率高的老年代。
然后是分代收集理论:
- 年轻代:Eden + Survivor0 + Survivor1,默认比例 8:1:1。
- 老年代:存放长期存活的大对象。
- 元空间:JDK 8 后替代永久代。
年轻代对象经历一次 Minor GC 后年龄加 1,默认年龄到 15 会晋升老年代,这个阈值可以通过参数-XX:MaxTenuringThreshold调整。
5.4 三色标记详解
三色标记是并发标记阶段的核心算法,也是面试中区分“懂原理”和“背概念”的关键题。
三个颜色含义:
- 白色:未访问对象。
- 灰色:自身已访问,但成员变量未全部访问。
- 黑色:自身和成员变量都已访问。
标记过程从 GC Roots 开始,初始标记后所有可达对象按规则从白色变为灰色,再从灰色变为黑色。最终剩下白色的对象被认为不可达,可以被回收。
面试必问题:三色标记为什么会产生漏标问题,怎么解决。
漏标的核心场景:一个黑色对象 B 引用了白色对象 W,同时灰色对象 A 到 W 的引用被切断。此时 W 变成黑色对象不可见的白色对象,但 W 实际是可达的。
解决方式有两种:
- 增量更新:黑色对象指向白色对象时,记录这个引用,重新标记阶段以黑色对象为根再扫描一次。CMS 使用增量更新。
- 原始快照 SATB:灰色对象断开白色对象引用时,记录该引用,重新标记阶段再扫描这个引用链。G1 使用原始快照。
面试答题建议:
“三色标记产生的根本原因是并发标记过程中引用关系发生变化。解决思路是破坏漏标的两个必要条件之一:要么记录黑色对象新增的引用,要么记录灰色对象删除的引用。CMS 用增量更新,G1 用 SATB。”
这样回答既讲清了原理,也点明了 CMS 和 G1 的差异,面试官很容易接下去问“那 G1 的整个回收流程是怎样的”。
5.5 垃圾收集器对比
常见收集器:
| 收集器 | 线程 | 算法 | 适用场景 |
|---|---|---|---|
| Serial | 单线程 | 复制(年轻代) | 单核或客户端模式 |
| Parallel Scavenge | 多线程 | 复制 | 高吞吐优先,JDK 8 默认 |
| CMS | 多线程 | 标记-清除 | 低延迟优先,JDK 9 弃用 |
| G1 | 多线程 | Region 化 | JDK 9+ 默认,兼顾延迟与吞吐 |
| ZGC | 多线程 | 着色指针 | 超大堆、极低停顿 |
G1 的 Region 划分是另一个高频考点。G1 把堆划分为大小相等的 Region,每个 Region 可以是 Eden、Survivor、Old 或 Humongous,大对象直接占用 Humongous Region。G1 通过维护 RSet 记录 Region 之间的引用关系,使回收不需要全堆扫描。
6. JVM 性能调优实战
性能调优是面试中“看起来会、实际答不深”的板块。很多人知道-Xmx、-Xms,但说不清怎么分析 GC 日志、怎么定位频繁 Full GC。
6.1 JVM 常用参数速查
# 堆内存参数 -Xms512m -Xmx2g -Xmn512m -XX:MaxMetaspaceSize=512m -XX:NewRatio=2 -XX:SurvivorRatio=8 # 垃圾回收器参数 -XX:+UseG1GC -XX:+UseParallelGC -XX:MaxGCPauseMillis=100 -XX:ParallelGCThreads=4 # GC 日志参数(JDK 8) -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/tmp/gc.log # 堆溢出自动转储 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof一个完整的启动示例:
java -Xms512m -Xmx2g -Xmn512m \ -XX:+UseG1GC \ -XX:MaxGCPauseMillis=100 \ -XX:+HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath=/tmp/app-heap.hprof \ -Xloggc:/tmp/app-gc.log \ -jar your-app.jar6.2 调优步骤
JVM 调优不是一上来就改参数,而是先发现问题,再验证方案。
通用排查流程:
- 查看进程状态:
jps -l确认目标进程 PID。 - 观察 GC 情况:
jstat -gc <pid> 1000每秒打印一次 GC 统计。 - 分析 GC 日志:重点看 Full GC 的次数和耗时。
- 获取堆快照:
jmap -dump:format=b,file=/tmp/heap.hprof <pid>。 - 查看线程栈:
jstack <pid>排查死锁和线程阻塞。 - 结合业务场景调整参数。
举一个高频案例:老年代空间不足导致 Full GC 频繁。可以先检查jstat -gc中FGC和FGCT的值,再用jmap -heap查看老年代空间占比。如果老年代在 Full GC 后仍然长期高位,说明有大量对象晋升或内存泄漏,需要通过堆转储分析对象引用链,而不是盲目调大堆内存。
6.3 调优工具
JDK 自带的jvisualvm在 JDK 8 中可以直接使用,JDK 9 之后不再随 JDK 发布,可改用jcmd或第三方工具。重点是掌握命令行工具,因为面试和线上排查中命令行工具使用频率最高。
# 查看 Java 进程 jps -l # 查看进程 12345 的堆信息 jmap -heap 12345 # 查看线程栈 jstack 12345 > thread_dump.txt学会读 GC 日志,比背调优参数更重要。GC 日志里的GC (Allocation Failure)、Full GC、停顿时间这些关键字,都是面试官会用来考你实战能力的。
7. MySQL 面试题联动复习
这套面试题把 MySQL 放进来的原因很直接:线上性能问题往往是 JVM 和数据库同时出问题,面试官需要看你能不能分清“是先查 GC 还是先查慢 SQL”。
7.1 索引相关高频题
MySQL 索引题里最常见的是:
- 为什么用 B+ 树而不是红黑树或哈希表。
- 什么是覆盖索引。
- 最左前缀原则。
- 索引失效的常见场景。
一个简单验证索引是否生效的示例:
CREATE TABLE user ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, age INT NOT NULL, email VARCHAR(100), KEY idx_name_age (name, age) ) ENGINE=InnoDB; -- 使用联合索引 EXPLAIN SELECT * FROM user WHERE name = '张三' AND age = 25; -- 不满足最左前缀,索引可能失效 EXPLAIN SELECT * FROM user WHERE age = 25;在本地 MySQL 执行EXPLAIN后,重点看type、key、rows三列。type从ALL(全表扫描)到ref、range、const的变化,能直观回答“为什么索引能加速查询”。
7.2 事务隔离级别与锁
MySQL 面试题中事务隔离级别和 JVM 并发内存模型有很强的对照关系:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交 | 可能 | 可能 | 可能 |
| 读已提交 | 不会 | 可能 | 可能 |
| 可重复读 | 不会 | 不会 | 可能(InnoDB 通过间隙锁解决) |
| 串行化 | 不会 | 不会 | 不会 |
面试答题时可以这样串联:在可重复读级别下,快照读通过 MVCC 保证一致性,当前读通过 Record Lock + Gap Lock 防止幻读。这道题很适合放在 JVM 并发相关题目之后,因为 MVCC 里的版本链思想和 JVM 对象头里的 Mark Word 存储 GC 年龄、锁状态的设计思路有共通之处。
7.3 JVM 和 MySQL 的排查顺序问题
一个经典的场景题:线上接口变慢,CPU 飙升,你怎么排查。
正确思路是:
top查看 CPU 和进程。jstack看线程堆栈,确认是否在 GC、是否死锁、是否有线程阻塞。jstat -gc看 Full GC 频率。show processlist;看数据库慢查询。EXPLAIN分析慢 SQL。
这个排查链路本身就是 JVM 面试题和 MySQL 面试题的交叉考点,把这套思路练熟,比单独背 20 道 JVM 题更有价值。
8. 面试自测与效果验证
学了大量知识后,如何确认自己真的掌握了?建议用“自测 + 实验验证”的方式。
8.1 自测清单
你可以在纸上或笔记里列出几个核心问题,不看书直接口述回答,每道题限制 2 到 3 分钟。
- 一个类从加载到卸载的完整过程是什么?
- 双亲委派模型的作用是什么?为什么 Tomcat 要破坏它?
- JVM 运行时数据区哪些线程共享、哪些线程私有?
- 对象创建过程包含哪些步骤?
- 判断对象是否可以回收的方法有哪些?
- 三色标记中漏标问题产生的条件是什么?CMS 和 G1 各怎么解决?
- G1 的 Region、RSet、SATB 分别做什么?
- 什么时候对象会进入老年代?
- 如何查看一个 Java 进程的 GC 情况?
- MySQL 可重复读级别下,为什么没有幻读问题?
这道题是联动的,能用“MVCC 快照读 + 间隙锁当前读”回答完整,说明你不仅理解了 MySQL,也对 JVM 的对象状态和并发机制有了类比认知。
8.2 动手实验验证
面试题不能只看,要做两个简单实验。
实验一:制造堆溢出并分析堆转储文件。
import java.util.ArrayList; import java.util.List; public class HeapOomDemo { public static void main(String[] args) throws InterruptedException { List<byte[]> list = new ArrayList<>(); int i = 0; while (true) { list.add(new byte[1024 * 1024]); i++; System.out.println("添加第 " + i + " 个 1MB 数组"); Thread.sleep(50); } } }启动时限制堆大小:
java -Xms64m -Xmx64m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/oom.hprof HeapOomDemo运行到内存不足后会抛出java.lang.OutOfMemoryError: Java heap space,并生成堆转储文件。这时用jmap -heap <pid>或可视化工具打开 hprof 文件,查看哪个对象占用了最多内存。这个实验能帮你真正理解“堆内存布局”和“OOM 排查”两个面试考点。
实验二:使用 jstat 观察对象晋升。
写一个循环创建对象的小程序,通过jstat -gc观察 Eden 区使用率和 Young GC 次数变化:
jstat -gc <pid> 1000输出中E代表 Eden 区容量,EU代表 Eden 区使用量,YGC是 Young GC 次数,FGC是 Full GC 次数。观察几轮后,你就能直观感受到对象的分配与回收。
8.3 效果判断标准
判断标准不是“能说出名词”,而是能不看资料完成:
- 画出 JVM 运行时数据区完整结构。
- 画出类加载过程的流程图。
- 用口述解释三色标记的漏标场景和两种解决方式。
- 对于一个模拟 OOM 程序,能定位到堆中占用最大的对象。
- 使用
EXPLAIN分析一条 SQL 是否命中索引。
满足其中四条以上,这套面试题基本掌握到位。
9. 常见问题与学习中的坑
在复习过程中,几乎每个人都会遇到下面这些情况。
| 问题现象 | 可能原因 | 排查思路 | 解决方案 |
|---|---|---|---|
| 命令行 java -version 版本不对 | 安装了多个 JDK,JAVA_HOME 或 PATH 配置错误 | echo $JAVA_HOME、which java | 重新配置 JAVA_HOME 并调整 PATH 顺序 |
| Eclipse 启动报“找不到或无法加载主类 org.apache.catalina.startup.Bootstrap” | Tomcat 运行环境 JDK 配置错误或 Tomcat 服务被中断 | 检查 Tomcat bin/setclasspath.bat、JAVA_HOME 指向 | 重新配置 JDK 路径,清理 Tomcat work 目录 |
| eclipse 启动报“no jvm could be found on your system” | Eclipse 未找到 JVM 或 JRE 路径失效 | 检查 eclipse.ini 中的 -vm 配置 | 在 eclipse.ini 中显式指定 jvm.dll 路径 |
| jstat 连接不上进程 | PID 写错或进程是非 Java 进程 | jps -l确认 PID | 使用正确 PID |
| 堆溢出 OOM 但 hprof 文件未生成 | 启动参数漏了 HeapDumpOnOutOfMemoryError | 检查启动命令 | 加上-XX:+HeapDumpOnOutOfMemoryError |
| GC 日志文件为空 | JDK 8 后参数变了 | 确认 JDK 版本 | JDK 9+ 使用-Xlog:gc* |
| MySQL 连接报“[error] could not get jvm parameters ...” | 这是 JVM 参数读取错误,常见于部分工具调用 MySQL 时 | 检查客户端和 JDK 版本兼容性 | 使用新版客户端或调整 JVM 参数 |
| MySQL 8.0 连接被拒 | 认证插件问题或端口未开放 | 检查 user 表 plugin 字段 | 改为 mysql_native_password 或使用新版驱动 |
| 复习后概念能背但面试答不完整 | 知识没有串成链路 | 用“答题模板”方式重练 | 每道题按“流程 + 原因 + 例子”三段式口述 |
注意“jvm参数 -xx:compilethreshold”这类热搜词,实际对应的是 JIT 编译阈值。-XX:CompileThreshold默认值在 C1 模式下是 1500,C2 模式下是 10000,意思是方法调用达到阈值后触发 JIT 编译。面试中这通常不是高频题,但如果被问到 JIT 编译,能说出这个参数说明你理解较深入。
另一个容易踩的坑是 Docker 容器里的 JVM 参数问题。容器部署的 Java 程序异常重启时,先看OOMKilled是否由容器内存限制导致。JVM 默认在容器中可能识别不到 cgroup 限制,需要显式设置-XX:MaxRAMPercentage。这也是现代面试中越来越常被问到的新题。
10. 复习最佳实践与建议
最后给一套可以直接执行的复习节奏。
10.1 三阶段复习法
第一阶段:梳理概念,建议用 3 到 5 天。把类加载、运行时数据区、GC 算法、收集器、三色标记、调优参数梳理成思维导图。不要追求记住所有参数,先建立整体结构。
第二阶段:实验验证,建议用 2 到 3 天。完成堆溢出实验、死锁实验、GC 日志分析、MySQLEXPLAIN分析。这一阶段的目的是把概念和现象对应起来。
第三阶段:口述练习,建议用 2 到 3 天。每道题限时口述,录音后回听,找出表达不完整的部分。重点练三色标记、G1 回收流程、对象晋升规则这三道深度题。
10.2 工程化建议
- 本地保留一套 JDK 8 和 JDK 17 的切换脚本,方便对比不同 GC 行为。
- 所有 OOM 实验和死锁实验写在单独的测试项目里,不要混入业务项目,避免影响正常代码。
- 每个实验保存一份 GC 日志和堆转储截图,面试前可以快速回顾。
- MySQL 索引实验只在自己的本地库中执行。
- 涉及生产环境或他人系统的数据,一律不要做锁表、删除、压测操作。
10.3 不推荐的复习方式
- 把 45 道题答案逐字背下来,面试官换一个问法就卡住。
- 只看文章不敲命令,JVM 调优的很多细节只有实际操作才能体会。
- 跳过三色标记,认为太偏。实际上,只要问到 G1 或 CMS,三色标记几乎是必聊话题。
- 把 JVM 和 MySQL 分开复习,忽略两者之间的联系。现在大厂面试更喜欢问“线上问题排查”这类综合场景题。
11. 总结与下一步
这套 JVM 面试 45 问,最值得投入时间的地方不是背答案,而是把类加载、内存模型、GC 原理、三色标记、性能调优和 MySQL 高频题合成一条完整的排查链路。最先应该验证的是堆溢出实验和 GC 日志分析,这是最快把“我会背概念”变成“我真的理解”的方式。最容易踩的坑是只看不练,以及把三色标记当成一个孤立难点。
下一步建议:先按第 3 节搭好 JDK 环境,再用第 8 节的实验代码复现一次 OOM,最后做一次完整的面试口述录音。当你能在 3 分钟内把“对象创建流程 → GC Roots 可达性分析 → 三色标记 → G1 回收”讲完,这套知识体系基本就稳了。