Java垃圾收集机制:核心算法、收集器与调优实践

265 阅读3分钟

Java垃圾收集机制:核心算法、收集器与调优实践


一、垃圾收集算法:内存的清洁工

垃圾收集算法是 JVM 回收内存的核心。

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

  • 原理:首先标记所有存活的对象,然后清除所有未标记的对象。
  • 优点:实现简单。
  • 缺点:会产生大量的内存碎片

2. 复制算法(Copying)

  • 原理:将内存划分为两个大小相等的区域(From 区和 To 区)。每次回收时,将存活对象从 From复制To 区,然后清空 From 区。
  • 优点:不会产生内存碎片,回收效率高。
  • 缺点:内存利用率低,只适用于对象存活率低的新生代。

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

  • 原理:在标记存活对象后,将所有存活对象移动到内存的一端,然后直接清理掉边界外的内存。
  • 优点:内存连续,不会产生内存碎片。
  • 缺点:移动对象会增加 GC 停顿时间。

二、垃圾收集器:算法的具体实现

垃圾收集器是垃圾收集算法的具体实现。在 JVM 中,有多种垃圾收集器,它们在停顿时间吞吐量之间做出了不同的权衡。

1. CMS(Concurrent Mark Sweep)

  • 目标低延迟
  • 工作流程CMS 采用“初始标记 -> 并发标记 -> 重新标记 -> 并发清除”的四阶段流程。其中,并发阶段允许 GC 线程和用户线程同时运行,从而减少了 GC 停顿时间。
  • 缺点:会产生内存碎片,且对 CPU 敏感。

2. G1(Garbage-First)

  • 目标:可预测的停顿时间
  • 核心思想:将堆内存划分为多个大小相等的 RegionG1 会优先回收垃圾最多的 RegionGarbage-First),从而实现可预测的 GC 停顿。
  • 优势G1 能够控制停顿时间(通过 -XX:MaxGCPauseMillis),且没有内存碎片问题。

3. ZGC/Shenandoah

  • 目标亚毫秒级停顿,适用于超大堆内存。

  • 核心思想

    • ZGC:使用染色指针技术,在指针中存储对象状态,实现了几乎完全并发的垃圾收集。
    • Shenandoah:使用转发指针技术,实现了并发整理,无需 STW 即可移动对象。

三、GC调优与日志分析

GC 调优是一个系统工程,需要结合 GC 参数和日志分析。

  • GC 参数

    • -Xmx:设置最大堆内存。
    • -XX:+UseG1GC:启用 G1 收集器。
    • -XX:MaxGCPauseMillis:设置最大 GC 停顿时间。
  • GC 日志:GC 日志记录了 GC 发生的时间、类型、停顿时间等信息。通过分析 GC 日志,可以定位 GC 瓶颈,并调整参数。

结论

理解垃圾收集算法和收集器的工作原理,是 JVM 性能优化的关键。开发者需要根据应用的特点(如吞吐量、延迟、内存大小),选择合适的垃圾收集器和参数,从而实现最佳的性能平衡。