一、基础理解篇
问题 1:JVM 的内存结构是什么样的?
参考回答:
JVM 在运行 Java 程序时,会把内存划分为若干区域:
-
程序计数器(PC Register): 每个线程独有,记录当前执行的字节码行号;
-
虚拟机栈(Java Stack): 保存局部变量、操作数栈、返回地址;
-
本地方法栈(Native Method Stack): 为本地(JNI)方法服务;
-
堆(Heap): 存放对象实例;
-
方法区(Method Area / Metaspace): 存放类的元数据、常量、静态变量等。
追问:
-
堆与方法区的区别是什么?
堆存对象,方法区存类的结构信息。
-
JDK8 后为什么去掉 PermGen?
因为 PermGen 容量固定且容易 OOM,Metaspace 使用本地内存,更灵活。
关键点总结:
-
能清晰说出各区域作用;
-
提及 JDK8 的 Metaspace 改动;
-
面试官重点看你是否理解"堆 vs 方法区 vs 栈"。
二、垃圾回收(GC)篇
问题 2:说说 Minor GC、Major GC 和 Full GC 的区别?
参考回答:
-
Minor GC: 只清理新生代,频率高,耗时短;
-
Major GC(或 Old GC): 清理老年代;
-
Full GC: 清理新生代 + 老年代 + 方法区,耗时最长,伴随 Stop The World。
追问:
-
哪些情况会触发 Full GC?
-
老年代空间不足;
-
元空间溢出;
-
显式调用 System.gc();
-
动态加载大量类(例如 Web 热部署)。
-
-
如何减少 Full GC?
-
优化对象生命周期;
-
调整新生代与老年代比例;
-
避免过多大对象创建。
-
关键点总结:
-
清楚区分三种 GC;
-
讲得出触发条件;
-
能提调优建议;
-
面试官喜欢听"分析 + 优化思路"。
问题 3:GC Roots 是什么?对象如何被判定为可回收?
参考回答:
GC Roots 是垃圾回收的起点对象,主要包括:
-
栈中的局部变量;
-
方法区中的静态引用;
-
JNI 引用;
-
被同步锁持有的对象。
JVM 采用 可达性分析算法(Reachability Analysis),
从 GC Roots 开始遍历引用链,不可达的对象即为可回收对象。
追问:
-
什么是引用计数法?为什么不用它?
计数器无法解决循环引用问题。
-
Java 中有哪些引用类型?
强、软、弱、虚引用。
关键点总结:
-
回答结构要"定义 → 判定算法 → 典型引用类型";
-
面试官喜欢考你"强引用导致内存泄漏"问题。
三、调优与排查篇
问题 4:线上 JVM 内存泄漏该如何排查?
参考回答:
-
确认问题:
- 观察 Full GC 频繁,内存占用居高不下;
-
定位阶段:
-
jstat -gcutil <pid> 查看 GC 情况;
-
jmap -histo:live <pid> 查看对象分布;
-
导出堆快照 jmap -dump:live,format=b,file=heap.hprof <pid>;
-
用 MAT / VisualVM 分析泄漏对象;
-
-
解决阶段:
-
释放静态集合;
-
关闭流;
-
清理缓存;
-
优化对象引用生命周期。
-
追问:
-
如何判断是"泄漏"而非"缓存增长正常"?
看对象数量是否长期不下降、GC 后仍无法回收。
-
你用过哪些工具?
jconsole、VisualVM、MAT、Arthas。
关键点总结:
-
一定要提"堆转储分析";
-
面试官想看你是否真的动手排查过问题。
问题 5:JVM 调优参数你一般怎么设置?
参考回答:
-Xms4G -Xmx4G -Xmn2G \
-XX:SurvivorRatio=8 \
-XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-XX:+PrintGCDetails \
-XX:+HeapDumpOnOutOfMemoryError \
-XX:HeapDumpPath=/data/logs/dump.hprof
解释要点:
-
初始堆与最大堆设为一致,避免动态扩容;
-
调整新生代比例;
-
使用 G1GC 以平衡延迟;
-
打印 GC 日志便于分析。
追问:
-
为什么要固定 -Xms 与 -Xmx?
避免频繁扩容带来的性能抖动;
-
如何选择合适的 GC?
取决于场景:低延迟选 G1/ZGC,吞吐量优先选 Parallel GC。
关键点总结:
-
参数 + 解释 + 背后原理;
-
面试官看的是"你是否懂得权衡"。
问题 6:常见 GC 收集器有哪些?各有什么特点?
收集器 | 代别 | 特点 | 适用场景 |
---|---|---|---|
Serial | 新生代 | 单线程 | 单核、小内存 |
Parallel | 新生代 | 多线程,吞吐量优先 | 后台批处理 |
CMS | 老年代 | 并发收集,低延迟 | Web 系统 |
G1 | 整堆 | 区块化管理,平衡吞吐与延迟 | 大内存应用 |
ZGC / Shenandoah | 整堆 | 超低延迟 (<10ms) | 低延迟系统 |
追问:
-
CMS 为什么被 G1 取代?
CMS 无法整理碎片、调优复杂,G1 自带压缩。
-
G1 的原理?
将堆划分为多个 Region,优先回收垃圾最多的区域。
关键点总结:
-
熟记对比表;
-
会说"CMS 缺点 + G1 优势"。
问题 7:如果线上系统频繁 Full GC,你会怎么处理?
参考回答:
-
确认现象:应用卡顿、日志显示频繁 Full GC;
-
初步定位:
-
jstat -gcutil <pid> 1000 10
-
jmap -histo:live 统计对象占比;
-
-
分析原因:
-
老年代爆满;
-
大对象频繁分配;
-
内存泄漏;
-
-
优化措施:
-
减少对象创建;
-
调整堆与新生代比例;
-
优化缓存;
-
使用 G1GC。
-
追问:
-
你如何判断 Full GC 是正常还是异常?
结合 QPS、GC 日志分析,观察停顿时长、内存回收比例。
关键点总结:
-
步骤分明(现象 → 定位 → 原因 → 优化);
-
面试官看"逻辑思路"。
四、高级优化篇
问题 8:请你讲一下 G1 GC 的工作原理?
参考回答:
-
G1 将堆划分为若干个相同大小的 Region;
-
新生代与老年代不再物理分区;
-
每次 GC 优先回收"垃圾最多"的 Region;
-
采用 Remembered Set 追踪跨 Region 引用;
-
可以通过 -XX:MaxGCPauseMillis 控制停顿目标。
追问:
-
G1 如何实现停顿可控?
基于历史统计预测回收收益,动态决定本次回收的 Region 数量。
-
G1 有什么缺点?
调优复杂、对小堆收益有限。
关键点总结:
-
说出"Region + 优先回收 + 停顿预测";
-
面试官考察你是否理解 G1 的设计思想。
问题 9:ZGC 是如何实现几乎无停顿的?
参考回答:
-
采用 Colored Pointer 技术,通过指针标记对象状态;
-
支持并发标记、并发重定位;
-
垃圾回收与应用线程几乎完全并行;
-
停顿时间通常 < 10ms。
追问:
-
和 G1 的主要区别是什么?
G1 仍需部分 Stop The World,ZGC 则实现全并发;
-
缺点?
吞吐量略低,内存开销较大。
关键点总结:
-
懂得提"Colored Pointer"、"并发压缩";
-
面试官重点看你是否了解新一代 GC 的原理。
五、实战经验篇
问题 10:你有做过哪些 JVM 调优实战?
高分参考回答:
在一次活动高峰期系统响应变慢,通过监控发现 Full GC 频繁。
用 jstat 和 GC 日志 发现老年代频繁触顶。
进一步分析发现某缓存未设置过期时间,导致对象长期占用内存。
优化后减少了 80% Full GC 次数,响应时间下降 40%。
追问:
-
你怎么验证优化效果?
优化前后对比 GC 日志、TPS、内存使用曲线;
-
如果是吞吐量问题呢?
改用 Parallel GC,并调大堆内存。
关键点总结:
-
一定要举"真实案例";
-
面试官喜欢"排查工具 + 数据支撑 + 结果改善"。
六、总结:高分答题套路
面试阶段 | 答题重点 |
---|---|
理论基础 | JVM 内存模型、GC 分类、引用机制 |
实战能力 | 内存泄漏排查、GC 优化、性能压测 |
参数掌握 | 说出常用参数及含义 |
原理理解 | 理解 G1、ZGC 设计思路 |
案例经验 | 能讲一个优化案例 |