JVM 面试高频题与知识体系复盘
JVM 面试覆盖面广,但考点相对集中。本文把知识体系梳理为六大模块,每个模块提炼高频题与答题要点,帮助建立"由点到面"的应答结构。
知识体系总览
JVM 知识体系
├── 内存管理 运行时数据区、对象创建、内存泄漏
├── 垃圾回收 GC 算法、回收器选型、调优
├── 类加载 加载/链接/初始化、双亲委派、打破委派
├── JMM 与并发 happens-before、volatile、synchronized
├── 调优与诊断 工具、OOM 排查、性能分析
└── 新特性 ZGC、GraalVM、JFR面试答题原则:先给结论,再展开原理,最后落到实践(参数/工具/案例)。下面按模块给出高频题与要点。
模块一:内存管理
1. JVM 运行时数据区有哪些?哪些线程共享?
要点:六大区域——堆与方法区(元空间)线程共享;虚拟机栈、本地方法栈、程序计数器线程私有;直接内存属堆外。
2. 对象创建到回收的完整流程?
要点:类加载检查 → 分配内存(指针碰撞/空闲列表,TLAB)→ 初始化零值 → 设置对象头 → 执行构造方法 → 后续 GC 回收。答出 TLAB、大对象直入老年代、年龄晋升加分。
3. 内存泄漏与内存溢出的区别?常见泄漏场景?
要点:泄漏是对象无法回收但不再使用(静态集合、ThreadLocal、连接未关闭、监听器未注销);溢出是内存耗尽抛 OOM。先定位泄漏再谈调参。
模块二:垃圾回收
4. GC 判定对象可回收的方式?
要点:可达性分析(GC Roots 出发),引用计数无法解决循环引用。GC Roots 包括栈引用、静态引用、常量引用、JNI 引用、活跃线程。
5. 三种基础 GC 算法与适用场景?
要点:标记-清除(碎片)、标记-复制(新生代,利用率 50%)、标记-整理(老年代,无碎片)。答出"分代收集"与"跨代引用用 RSet"更完整。
6. 如何选择垃圾回收器?
要点:按延迟/吞吐/堆大小。JDK 8 默认 Parallel(高吞吐);响应敏感用 G1;超大堆低延迟用 ZGC/Shenandoah。答出 G1 Region、SATB、Mixed GC 加分。
7. 什么是三色标记?如何解决并发标记漏标?
要点:白/灰/黑三色;并发修改导致漏标。CMS 用增量更新(记录新增引用),G1/ZGC 用原始快照(SATB,记录删除的引用)。
模块三:类加载
8. 类加载过程有哪些阶段?
要点:加载 → 验证 → 准备 → 解析 → 初始化 → 使用 → 卸载。重点:准备阶段赋零值(static final 除外),初始化执行 <clinit>。
9. 双亲委派模型及其意义?
要点:子类加载器先委派父类;避免重复加载、保护核心类(String 不被替换)。
10. 如何打破双亲委派?举例。
要点:重写 loadClass(Tomcat WebAppClassLoader)、线程上下文类加载器(JDBC SPI)、OSGi/模块化。答出"为什么要打破"(隔离、反向加载 SPI 实现)。
模块四:JMM 与并发
11. volatile 的作用?能否保证原子性?
要点:可见性 + 有序性(禁止重排),不保证原子性。DCL 单例为什么需要 volatile——防止 new 的引用赋值重排到初始化前。
12. happens-before 规则有哪些?
要点:程序次序、管程锁定、volatile、线程启动/终止/中断、对象终结、传递性。重点答传递性与锁/volatile 规则。
13. synchronized 的锁升级过程?
要点:无锁 → 偏向锁 → 轻量级锁 → 重量级锁。偏向锁 CAS 写线程 ID;轻量级锁 CAS 复制 Mark Word;重量级锁 Monitor + 阻塞。可补充自旋与锁消除/粗化。
模块五:调优与诊断
14. JVM 调优的思路?
要点:先观察(GC 日志、jstat)→ 分析(频率、停顿、晋升速率)→ 单变量调整 → 验证。给出场景题答案(如 Full GC 频繁 → 堆小/泄漏/大对象)。
15. OOM 排查步骤?
要点:看异常类型(heap/Metaspace/thread)→ 开启 HeapDumpOnOutOfMemoryError → jmap -histo 初筛 → MAT/VisualVM 分析引用链 → 源码定位。
16. 常用 JVM 监控工具?
要点:jps 找进程、jstat 看 GC、jmap 堆转储、jstack 线程栈、jcmd 统一诊断、JFR 低开销录制、Arthas 在线诊断。
模块六:新特性与扩展
17. G1 与 ZGC 的核心区别?
要点:G1 是 Region 分代 + 停顿预测,有 STW 标记/整理阶段;ZGC 全并发(标记/转移/重映射)+ 染色指针 + 读屏障,停顿 <10ms 且不随堆增长。可补充分代 ZGC。
18. JFR 相比传统监控工具的优势?
要点:低开销(<1%)、连续记录(可回溯事故前)、事件级数据(GC/锁/分配热点)、运行期启停无需重启。
19. GraalVM Native Image 的原理与限制?
要点:AOT 静态编译、封闭世界分析;启动快内存低;反射/动态代理需配置,不支持运行期动态类加载。
场景题速答
场景:Full GC 频繁
问:应用 Full GC 频繁,如何排查?
答:
1. jstat -gccause 确认 FGC 频率与原因
2. 确认堆是否偏小(-Xmx 与物理内存)
3. jmap -histo 看是否有异常大对象/泄漏
4. 开启 HeapDumpOnOutOfMemoryError 或手动转储
5. MAT 分析支配树与 GC Roots 引用链
6. 常见结论:缓存无界、静态集合泄漏、大对象直入老年代、堆参数不合理场景:启动慢 / 冷启动要求高
问:服务要求秒级启动,怎么办?
答:
1. 减少类加载与初始化开销(懒加载、按需初始化)
2. 评估 AOT 方案:GraalVM Native Image(毫秒级启动)
3. 配合 Spring Boot 3 / Quarkus 的原生支持场景:接口延迟抖动
问:接口 P99 偶发超时,如何定位?
答:
1. 常驻 JFR 录制,复现后导出分析
2. JMC 看 GC 停顿 / 火焰图 / 锁竞争事件
3. trace 接口方法定位耗时子调用
4. 按定位结果调整:GC 参数、锁粒度、缓存策略答题技巧总结
- 结论先行:先给一句话结论,再展开原理,避免冗长铺垫
- 原理 + 实践结合:每个理论点后接参数或工具示例,体现实战能力
- 注意边界:volatile 不保证原子性、G1 会 Full GC、偏向锁已移除等"反直觉"点更能体现深度
- 横向对比:ZGC vs G1、增量更新 vs SATB、Native Image vs JVM 等对比题是加分项