JVM 面试题
目录概述
JVM 是理解 Java 程序运行本质的关键,也是区分"会用"和"理解原理"的重要分水岭。内存模型、垃圾回收、类加载机制——每一块都能追问到操作系统层面。
这个目录帮你从"写 Java 代码"进阶到"理解 Java 程序是怎么在机器上运行的"。
【面试官心理】 我出 JVM 题,不是为了考你背参数。通常是从一个生产问题出发:"你们的线上服务 GC 时间从 50ms 突然变成 2s,怎么排查?" 能讲出完整排查路径的人,说明他真的在生产环境处理过 GC 问题。
内容范围
核心主题
内存模型:
- JVM 内存结构:堆、栈、方法区、程序计数器、本地方法栈
- 堆内存分区:年轻代、老年代、 Eden 区、Survivor 区
- 栈帧结构:局部变量表、操作数栈、动态链接、方法返回地址
- 方法区演进:永久代 vs 元空间(JDK 7 vs JDK 8)
垃圾回收:
- 垃圾判定算法:引用计数、可达性分析
- 垃圾回收算法:标记-清除、复制、标记-整理
- 分代收集理论:年轻代、老年代、永久代/元空间
- 经典垃圾收集器:Serial、ParNew、Parallel Scavenge、CMS、G1、ZGC、Shenandoah
- CMS 收集器:并发标记、三色标记、增量更新、原始快照
- G1 收集器:Region 设计、Humongous 区域、Remembered Set
- ZGC 收集器:染色指针、读屏障、并发执行
类加载机制:
- 类加载过程:加载、验证、准备、解析、初始化
- 类加载器分类:Bootstrap、Extension、Application、自定义类加载器
- 双亲委派模型:为什么需要、打破双亲委派的情况
- 类加载时机:主动使用 vs 被动使用、六种触发条件
- 线程上下文类加载器:SPI 机制、JDBC 驱动加载
JVM 性能调优:
- 常用 JVM 参数:堆大小设置、GC 选择、新生代比例
- 内存溢出排查:heap dump、MAT 分析、Arthas
- GC 日志分析:GCViewer、GCEasy
- 线上 JVM 参数配置案例
字节码与执行:
- 字节码指令集:常见指令、栈操作、局部变量访问
- 字节码工具:javap、ASM、ByteBuddy
- JIT 编译器:解释执行 vs 编译执行、分层编译
- 逃逸分析:栈上分配、标量替换、锁消除
面试题分级
高频必考题 🔴
垃圾回收算法
面试官问:"JVM 有哪些垃圾回收算法?它们各自的优缺点是什么?"
能说出标记-清除、复制、标记-整理的占 80%,能讲清楚为什么年轻代用复制算法、老年代用标记-整理的占 40%,能说出分代收集理论依据的只有 20%。
【面试官心理】 我问他垃圾回收算法,其实想探查的是:他知不知道不同算法的适用场景。为什么年轻代用复制?是因为年轻代对象生命周期短,复制成本低。为什么老年代用标记-整理?是因为空间连续性重要,而且没有额外的空间用来复制。这种设计权衡才是面试官想听到的。
对象什么时候进入老年代
面试官问:"对象什么时候会进入老年代?"
能说出"长期存活的对象"的占 60%,能说出"大对象直接进入老年代"的占 50%,能说出"动态年龄判断"的占 30%,能说清楚 -XX:MaxTenuringThreshold 参数的只有 15%。
类加载过程
面试官问:"类的加载过程是什么?每个阶段做了什么?"
能背出"加载、验证、准备、解析、初始化"的占 80%,能讲清楚验证阶段检查什么的占 50%,能说出解析阶段是静态链接还是动态链接的占 30%,能说清楚什么情况下会触发初始化的只有 10%。
双亲委派模型
面试官问:"什么是双亲委派模型?为什么要打破它?"
能说出"向上委托、向下加载"的占 60%,能说出"沙箱安全"原因的占 40%,能举出打破双亲委派的实际案例(JDBC、SPI)的占 20%,能说清楚线程上下文类加载器怎么用的只有 10%。
中频常考题 🟡
- CMS 和 G1 的区别
- G1 的 Region 是什么
- ZGC 的染色指针
- 常见 OOM 场景
- JIT 编译优化
低频了解题 🟢
- 字节码指令详解
- ASM 框架使用
- GraalVM
- 栈上分配原理
学习路径指引
P5 候选人(校招/初级社招)
先掌握 JVM 内存结构、常见垃圾收集器、类加载基础。能说出堆栈区别、垃圾判定算法、各收集器特点即可。这个阶段不需要死磕底层原理。
P6 候选人(中级社招)
必须理解分代收集理论、垃圾收集器工作原理。CMS 和 G1 要能说出各自优缺点和适用场景。类加载机制要理解双亲委派模型和 SPI 机制。JVM 参数要有实战经验。
P7 候选人(高级/架构方向)
除了原理,必须有线上排查和性能调优经验。能用 Arthas、MAT、GCEasy 等工具分析生产问题。能针对不同业务场景给出 JVM 参数配置建议。能讲清楚 JDK 版本演进对 JVM 的影响。
【面试官心理】 P7 候选人聊 JVM,我通常会问:"你们线上用的什么垃圾收集器?为什么选它?有没有遇到过 GC 问题?怎么排查的?" 能讲出完整案例的候选人,我会追问他当时的 JVM 参数是什么、怎么调整的。这种真实经验比任何资料都值钱。
生产避坑
Full GC 频繁
常见原因:老年代空间不足、分配担保失败、内存碎片。排查工具:GC 日志、GCEasy、Arthas。解决方案:调整年轻代/老年代比例、选择合适的收集器、增加堆内存。
内存泄漏
常见场景:集合类未清理、静态集合、单例模式持有外部引用、ThreadLocal 未 remove。排查方法:heap dump、MAT 分析引用链。
线程饥饿
线程池配置不当、GC 停顿导致线程无法申请内存、锁竞争导致线程阻塞。