常见垃圾回收算法、垃圾回收器及 JVM 调优

常见垃圾回收算法、垃圾回收器及 JVM 调优


一、常见垃圾回收算法

1. 标记-清除算法(Mark-Sweep)

  • 原理
    • 标记阶段:从 GC Roots 出发,标记所有可达对象。
    • 清除阶段:回收未被标记的对象(即不可达对象)。
  • 特点
    • 优点:简单直接,不需要移动对象。
    • 缺点
      • 产生大量内存碎片(影响大对象分配)。
      • 标记和清除过程停顿时间长(STW,Stop-The-World)。
  • 适用场景:早期 JVM 或小型应用。

2. 复制算法(Copying)

  • 原理
    • 将内存分为两块(Eden 和 Survivor),每次只使用一块。
    • 存活对象复制到另一块内存,清空原内存。
  • 特点
    • 优点
      • 无内存碎片(对象连续存放)。
      • 分配内存只需移动指针(效率高)。
    • 缺点
      • 内存利用率低(仅使用一半内存)。
      • 复制过程需要 STW。
  • 适用场景:新生代(Young Generation),对象存活率低。

3. 标记-整理算法(Mark-Compact)

  • 原理
    • 标记阶段:标记所有可达对象。
    • 整理阶段:将存活对象向内存一端移动,清理边界外空间。
  • 特点
    • 优点
      • 无内存碎片(对象连续存放)。
      • 适合老年代(对象存活率高)。
    • 缺点
      • 整理过程需要 STW,停顿时间较长。
  • 适用场景:老年代(Old Generation)。

4. 分代收集算法(Generational Collection)

  • 原理
    • 将堆内存分为新生代(Young Gen)、老年代(Old Gen)和元空间(Metaspace)。
    • 不同区域采用不同回收算法:
      • 新生代:复制算法(对象存活率低)。
      • 老年代:标记-清除或标记-整理(对象存活率高)。
  • 特点
    • 优点:结合不同算法优势,提高效率。
    • 缺点:实现复杂。
  • 适用场景:现代 JVM 的主流方案(如 HotSpot)。

二、常见垃圾回收器

1. Serial GC(串行垃圾回收器)

  • 特点
    • 单线程执行 GC,STW 时间长。
    • 适用于客户端应用或小型 JVM。
  • 适用场景:单核 CPU 或小内存应用(如嵌入式系统)。

2. Parallel GC(并行垃圾回收器)

  • 特点
    • 多线程执行 GC,提高吞吐量(适合 CPU 密集型应用)。
    • 仍使用 STW,但停顿时间比 Serial GC 短。
  • 适用场景:多核 CPU 的批处理任务(如大数据计算)。

3. CMS(Concurrent Mark-Sweep)

  • 特点
    • 并发标记和清除:大部分阶段与用户线程并发执行,减少 STW 时间。
    • 缺点
      • 会产生内存碎片。
      • 可能出现“Concurrent Mode Failure”(并发失败时退化为 Serial Old)。
  • 适用场景:低延迟应用(如 Web 服务)。
  • 注意:JDK 9 后被废弃,推荐 G1。

4. G1(Garbage-First)

  • 特点
    • 分代 + 区域化:将堆划分为多个 Region,灵活调整新生代和老年代大小。
    • 并发 + 并行:部分阶段并发执行,减少 STW 时间。
    • 可预测停顿:通过目标停顿时间(Pause Time Goal)控制 GC 行为。
  • 适用场景:大内存、低延迟应用(如微服务、大数据)。
  • JDK 默认:JDK 9+ 默认使用 G1。

5. ZGC(Z Garbage Collector)

  • 特点
    • 超低延迟:STW 时间通常 <10ms(适合金融、实时系统)。
    • 可扩展性:支持 TB 级堆内存。
    • 并发标记和整理:几乎全程并发执行。
  • 适用场景:超低延迟应用(如交易系统、实时计算)。
  • JDK 支持:JDK 11+ 实验性支持,JDK 15+ 正式 GA。

6. Shenandoah GC

  • 特点
    • 低延迟:STW 时间与堆大小无关(类似 ZGC)。
    • 并发压缩:减少内存碎片。
  • 适用场景:低延迟、大内存应用(如云原生服务)。
  • JDK 支持:JDK 12+ 实验性支持,JDK 17+ 正式 GA。

三、JVM 调优关键参数

1. 堆内存设置

-Xms<初始堆大小>    # 初始堆大小(如 -Xms2g)
-Xmx<最大堆大小>    # 最大堆大小(如 -Xmx4g)
-Xmn<新生代大小>    # 新生代大小(如 -Xmn1g)
  • 建议
    • -Xms-Xmx 设置为相同值,避免动态调整开销。
    • 新生代占比通常为堆的 1/3~1/2(如 -Xmn1g 对应 -Xmx3g)。

2. GC 选择

-XX:+UseSerialGC          # 使用 Serial GC
-XX:+UseParallelGC        # 使用 Parallel GC
-XX:+UseConcMarkSweepGC   # 使用 CMS(JDK 9+ 已废弃)
-XX:+UseG1GC              # 使用 G1(JDK 9+ 默认)
-XX:+UseZGC               # 使用 ZGC(JDK 11+)
-XX:+UseShenandoahGC      # 使用 Shenandoah GC(JDK 12+)

3. G1 特定参数

-XX:MaxGCPauseMillis=<毫秒>  # 目标最大停顿时间(默认 200ms)
-XX:InitiatingHeapOccupancyPercent=<百分比>  # 触发并发 GC 的堆占用率(默认 45%)

4. 元空间(Metaspace)设置

-XX:MetaspaceSize=<大小>    # 初始元空间大小(如 -XX:MetaspaceSize=256m)
-XX:MaxMetaspaceSize=<大小> # 最大元空间大小(如 -XX:MaxMetaspaceSize=512m)

5. 监控与诊断

-XX:+PrintGCDetails         # 打印 GC 详细日志
-XX:+PrintGCDateStamps      # 打印 GC 时间戳
-Xloggc:<文件路径>          # 将 GC 日志输出到文件
-XX:+HeapDumpOnOutOfMemoryError  # OOM 时生成堆转储文件
-XX:HeapDumpPath=<路径>     # 堆转储文件路径

四、JVM 调优策略

1. 新生代调优

  • 对象存活率低:增大新生代(减少 Minor GC 频率)。
  • 对象存活率高:减小新生代(避免频繁 Full GC)。

2. 老年代调优

  • 老年代空间不足
    • 增大堆大小(-Xmx)。
    • 调整 IHOP-XX:InitiatingHeapOccupancyPercent)提前触发并发 GC。
  • 频繁 Full GC
    • 检查是否有内存泄漏(使用 MAT 或 VisualVM 分析堆转储)。
    • 优化代码减少大对象分配。

3. 低延迟场景

  • 使用 G1/ZGC/Shenandoah 替代 CMS/Parallel GC。
  • 设置较小的 -XX:MaxGCPauseMillis(如 100ms)。

4. 高吞吐场景

  • 使用 Parallel GCG1(平衡吞吐与延迟)。
  • 增大堆大小以减少 GC 频率。

5. 监控与分析

  • 使用工具:
    • JVisualVM / JConsole(实时监控)。
    • MAT(Eclipse Memory Analyzer,分析堆转储)。
    • GC 日志分析工具(如 GCViewer、GCEasy)。

五、总结

类别关键点
垃圾回收算法标记-清除、复制、标记-整理、分代收集(现代 JVM 主流)。
垃圾回收器Serial(单线程)、Parallel(多线程)、CMS(已废弃)、G1(低延迟)、ZGC/Shenandoah(超低延迟)。
JVM 调优堆大小设置、GC 选择、元空间调整、监控工具(GC 日志、MAT)。
调优策略新生代/老年代优化、低延迟 vs 高吞吐、内存泄漏排查。

适用场景建议

  • 客户端应用:Serial GC 或 Parallel GC。
  • Web 服务:G1(默认)或 CMS(旧版 JDK)。
  • 金融/实时系统:ZGC 或 Shenandoah。
  • 大数据计算:Parallel GC(高吞吐)。

demo配置命令

java -Xms2g -Xmx4g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar your_app.jar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值