第3章 JVM调优与内存模型面试高频
JVM调优是Java分布式系统面试的必考点,涵盖内存分区、GC算法、参数配置与内存泄漏排查。本章以结构化问答+实战项目模板,帮助你在面试中体系化输出调优思路。
面试问题:JVM内存分区有哪些?各自作用是什么?
考察点:JVM运行时数据区划分、线程共享/私有特性、各区域存储内容,以及OOM对应区域。
回答框架:先明确分区→分别说明用途→指出区域与OOM的对应关系→结合调优举例。
示例回答:JVM内存分堆、方法区、虚拟机栈、本地方法栈和程序计数器。堆存对象实例,方法区存类信息、常量,栈存局部变量。堆和方法区线程共享,栈和PC线程私有。堆溢出多调整-Xmx,栈溢出增加-Xss。
可能追问:1. Java 8之后元空间替换了永久代,为什么要换?2. 字符串常量池在哪里?
避坑提醒:不要混淆堆和栈的作用;注意JDK版本差异(如永久代改为元空间)。
面试问题:常见的GC算法有哪些?CMS和G1的区别?
考察点:GC算法原理、垃圾收集器特性、适用场景、停顿时间与吞吐量的权衡。
回答框架:先列举算法→对比收集器→突出CMS与G1的核心差异(目标、内存布局、停顿模型)。
示例回答:标记-清除、标记-复制、标记-整理。CMS以低停顿为目标,使用标记-清除,可能产生碎片;G1面向大堆,将堆分Region,可预测停顿,整理阶段无碎片。低延迟选G1,吞吐量优先选Parallel。
可能追问:1. G1的Mixed GC如何选择CSet?2. CMS并发阶段如何解决三色标记问题?
避坑提醒:CMS只在老年代收集,G1全堆;G1年轻代回收和Mixed GC并存。不要混淆配置参数-XX:+UseConcMarkSweepGC和-XX:+UseG1GC。
面试问题:如何进行内存泄漏排查?
考察点:内存泄漏常见原因、监控与工具(jstat、jmap、MAT)、泄漏分析流程。
回答框架:先检测异常(GC频繁/OOM)→生成Heap Dump→分析Dominator Tree→定位泄漏对象→追溯代码。
示例回答:用jstat观察Old区持续增长,jmap dump堆,MAT查看大对象和GC Root路径。如HashMap缓存未清除导致泄漏,则改为WeakHashMap或设置上限。线上可用Arthas实时监控。
可能追问:1. 静态集合类为什么容易泄漏?2. 使用软引用和弱引用的区别及适用场景?
避坑提醒:生产环境dump前触发Full GC避免误判;MAT的支配树和入站引用要分清。不要在示例中提“maybe”之类的模糊词。
项目案例:高并发订单系统JVM调优实践
| 业务背景 | 电商大促期间,订单系统每秒峰值10万请求,出现频繁Stop-The-World,RT飙升。 |
| 规模指标 | 日订单量1亿+,QPS 8~10万,堆内存256GB(单机),GC停顿最高达500ms。 |
| 技术栈 | JDK 11, G1 GC, Prometheus + Grafana, 自研APM, Arthas |
| 核心难点 | 大堆下G1的Region数过多(~2048),IHOP阈值不合理导致并发回收失败。 |