Java 面试:JVM 垃圾回收器选择与调优策略

1. 垃圾回收器概述

JVM 垃圾回收器(GC)负责自动管理内存,核心目标是:

  • 吞吐量:单位时间内处理的任务量
  • 延迟:单次 GC 停顿时间
  • 内存占用:GC 自身消耗的堆空间
    三者需根据场景权衡,关系可表示为:
    $$ \text{吞吐量} \propto \frac{1}{\text{延迟}} \quad \text{且} \quad \text{内存占用} \propto \text{吞吐量} $$

2. 主流垃圾回收器及特点
回收器类型 适用场景 关键特性 停顿时间
Serial 客户端应用、小堆(<100MB) 单线程 STW
Parallel 后台计算、高吞吐需求 多线程并行 中等
CMS Web 服务、低延迟需求 并发标记清除 低(但碎片多)
G1 大堆(>4GB)、平衡吞吐与延迟 分区域收集、可预测停顿 可控
ZGC/Shenandoah 超大堆(>16GB)、极致低延迟 并发压缩、亚毫秒停顿 极低

STW(Stop-The-World):GC 时暂停所有应用线程


3. 选择策略

根据应用需求决策:

  • 高吞吐场景(如数据分析):
    优先选 Parallel Scavenge + Parallel Old,参数:-XX:+UseParallelGC
  • 低延迟场景(如实时交易):
    • 堆 < 4GB:CMS-XX:+UseConcMarkSweepGC
    • 堆 > 4GB:G1-XX:+UseG1GC
  • 超大堆+毫秒级停顿ZGC-XX:+UseZGC)或 Shenandoah-XX:+UseShenandoahGC

4. 调优策略
(1) 通用参数优化
# 堆大小设置(避免动态调整)
-Xms4g -Xmx4g           # 初始堆=最大堆
-XX:NewRatio=3          # 老年代:新生代=3:1
-XX:SurvivorRatio=8     # Eden:Survivor=8:1

(2) 针对回收器的优化
  • G1 调优
    -XX:MaxGCPauseMillis=200   # 目标最大停顿时间
    -XX:G1HeapRegionSize=4m    # 区域大小(默认按堆自动计算)
    

  • CMS 调优
    -XX:CMSInitiatingOccupancyFraction=70  # 老年代70%时触发GC
    -XX:+UseCMSCompactAtFullCollection     # 减少碎片
    

(3) 监控与诊断
  • 启用 GC 日志:
    -Xlog:gc*:file=gc.log:time,uptime,level,tags
    

  • 关键指标分析:
    • Full GC 频率:频繁 Full GC 需增大堆或调整代比例
    • 晋升失败:增加 -XX:MaxTenuringThreshold
    • 分配速率:若 $ \text{分配速率} > \text{回收速率} $,需优化对象创建

5. 面试常见问题
  1. CMS 和 G1 的区别?
    CMS 采用标记-清除算法,易产生碎片;G1 通过分区域设计减少全局停顿。
  2. 如何避免 OOM?
    • 分析堆转储(-XX:+HeapDumpOnOutOfMemoryError
    • 检查内存泄漏(如未关闭的 Connection
  3. ZGC 如何实现亚毫秒停顿?
    通过着色指针(Colored Pointers)和读屏障(Load Barriers)实现并发压缩。

调优黄金法则:优先满足业务需求,再通过增量调整优化 GC,避免过度调优。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐