【面试】Java JVM 调优面试手册

一、基础理解篇

问题 1:JVM 的内存结构是什么样的?

参考回答:

JVM 在运行 Java 程序时,会把内存划分为若干区域:

  • 程序计数器(PC Register): 每个线程独有,记录当前执行的字节码行号;

  • 虚拟机栈(Java Stack): 保存局部变量、操作数栈、返回地址;

  • 本地方法栈(Native Method Stack): 为本地(JNI)方法服务;

  • 堆(Heap): 存放对象实例;

  • 方法区(Method Area / Metaspace): 存放类的元数据、常量、静态变量等。

追问:

  1. 堆与方法区的区别是什么?

    堆存对象,方法区存类的结构信息。

  2. 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。

追问:

  1. 哪些情况会触发 Full GC?

    • 老年代空间不足;

    • 元空间溢出;

    • 显式调用 System.gc();

    • 动态加载大量类(例如 Web 热部署)。

  2. 如何减少 Full GC?

    • 优化对象生命周期;

    • 调整新生代与老年代比例;

    • 避免过多大对象创建。

关键点总结:

  • 清楚区分三种 GC;

  • 讲得出触发条件;

  • 能提调优建议;

  • 面试官喜欢听"分析 + 优化思路"。

问题 3:GC Roots 是什么?对象如何被判定为可回收?

参考回答:

GC Roots 是垃圾回收的起点对象,主要包括:

  • 栈中的局部变量;

  • 方法区中的静态引用;

  • JNI 引用;

  • 被同步锁持有的对象。

JVM 采用 可达性分析算法(Reachability Analysis),

从 GC Roots 开始遍历引用链,不可达的对象即为可回收对象。

追问:

  1. 什么是引用计数法?为什么不用它?

    计数器无法解决循环引用问题。

  2. Java 中有哪些引用类型?

    强、软、弱、虚引用。

关键点总结:

  • 回答结构要"定义 → 判定算法 → 典型引用类型";

  • 面试官喜欢考你"强引用导致内存泄漏"问题。

三、调优与排查篇

问题 4:线上 JVM 内存泄漏该如何排查?

参考回答:

  1. 确认问题:

    • 观察 Full GC 频繁,内存占用居高不下;
  2. 定位阶段:

    • jstat -gcutil <pid> 查看 GC 情况;

    • jmap -histo:live <pid> 查看对象分布;

    • 导出堆快照 jmap -dump:live,format=b,file=heap.hprof <pid>;

    • 用 MAT / VisualVM 分析泄漏对象;

  3. 解决阶段:

    • 释放静态集合;

    • 关闭流;

    • 清理缓存;

    • 优化对象引用生命周期。

追问:

  • 如何判断是"泄漏"而非"缓存增长正常"?

    看对象数量是否长期不下降、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) 低延迟系统

追问:

  1. CMS 为什么被 G1 取代?

    CMS 无法整理碎片、调优复杂,G1 自带压缩。

  2. G1 的原理?

    将堆划分为多个 Region,优先回收垃圾最多的区域。

关键点总结:

  • 熟记对比表;

  • 会说"CMS 缺点 + G1 优势"。

问题 7:如果线上系统频繁 Full GC,你会怎么处理?

参考回答:

  1. 确认现象:应用卡顿、日志显示频繁 Full GC;

  2. 初步定位

    • jstat -gcutil <pid> 1000 10

    • jmap -histo:live 统计对象占比;

  3. 分析原因

    • 老年代爆满;

    • 大对象频繁分配;

    • 内存泄漏;

  4. 优化措施

    • 减少对象创建;

    • 调整堆与新生代比例;

    • 优化缓存;

    • 使用 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 设计思路
案例经验 能讲一个优化案例
相关推荐
liulilittle3 小时前
VGW 虚拟路由器ARP剖析
开发语言·c++·编程语言·路由·sd·sdn·vgw
代码充电宝3 小时前
LeetCode 算法题【简单】290. 单词规律
java·算法·leetcode·职场和发展·哈希表
li3714908903 小时前
nginx报400bad request 请求头过大异常处理
java·运维·nginx
摇滚侠3 小时前
Spring Boot 项目, idea 控制台日志设置彩色
java·spring boot·intellij-idea
鸡吃丸子3 小时前
Next.js 入门指南
开发语言·javascript·next.js
wjs20244 小时前
《Foundation 滑块:界面设计的艺术与科学》
开发语言
Aevget4 小时前
「Java EE开发指南」用MyEclipse开发的EJB开发工具(二)
java·ide·java-ee·eclipse·myeclipse
黄昏晓x4 小时前
C++----多态
java·jvm·c++
William_cl4 小时前
【C# OOP 入门到精通】从基础概念到 MVC 实战(含 SOLID 原则与完整代码)
开发语言·c#·mvc