Java 的 G1 垃圾回收流程

Java 的 G1 垃圾回收流程

G1(Garbage-First)垃圾收集器 是一种区域化、并发、低延迟的垃圾回收器,适合大堆内存和对暂停时间有严格要求的应用程序。G1 的垃圾回收流程主要包括以下阶段:


1. 堆的区域化分区

在 G1 中,堆被分为多个大小相等的 Region,每个 Region 可以扮演以下角色之一:

  • Eden:存储新创建的对象。
  • Survivor:存储从 Eden 晋升的存活对象。
  • Old:存储长期存活的对象。
  • Humongous:存储超大对象(大小超过 Region 的 50%)。

2. 垃圾回收的主要阶段

2.1 年轻代垃圾回收(Young GC)

  • 触发条件:
    • Eden 区域内存耗尽。
  • 回收流程:
    1. STW 初始标记:暂停应用线程,标记所有 Eden 区和 Survivor 区中不再使用的对象。
    2. 复制存活对象:将存活对象从 Eden 复制到 Survivor 或 Old 区。
    3. 更新引用:修复堆中引用的指向。

2.2 并发标记阶段

并发标记阶段的目的是标记整个堆中所有存活对象,识别可以回收的区域。分为以下几个步骤:

  1. 初始标记(STW)
    • 标记 GC Roots 及直接可达对象。
    • 与 Young GC 结合运行,减少停顿。
  2. 并发标记
    • 遍历堆中的对象图,标记所有可达对象。
    • 与应用线程并发执行。
  3. 最终标记(STW)
    • 修正并发标记阶段遗漏的引用变化,处理 SATB 缓冲区。
  4. 清理阶段
    • 统计各区域的回收价值,确定需要回收的区域。

2.3 混合垃圾回收(Mixed GC)

  • 触发条件:
    • Old 区的内存使用达到一定比例(默认是 45%)。
  • 回收流程:
    1. 回收 Eden 和 Survivor 区。
    2. 按优先级回收部分 Old 区,优先清理垃圾比例最高的区域。
    3. 对回收的 Old 区进行整理(压缩)。

3. 关键机制

3.1 记忆集(Remembered Set)

  • 用于记录跨区域的引用,避免全堆扫描。
  • 每个 Region 都有一个 Remembered Set,记录指向该 Region 的引用。

3.2 分区优先级

  • G1 按区域的垃圾比例排序,优先回收垃圾比例高的区域,称为“Garbage-First”策略。

3.3 SATB(Snapshot-At-The-Beginning)

  • 在标记阶段使用快照集算法,记录堆在标记开始时的对象状态,确保标记过程一致性。

4. 回收阶段的 STW 停顿

G1 的设计目标是控制 STW 停顿时间:

  • 通过并发执行标记和回收任务,减少全堆停顿时间。
  • Mixed GC 和 Young GC 阶段的停顿时间由用户通过 -XX:MaxGCPauseMillis 配置。

5. 总结

G1 垃圾回收流程通过分区、并发标记和分阶段回收实现高效的垃圾收集:

  1. Young GC:快速回收新生代,减轻老年代压力。
  2. 并发标记:遍历整个堆,标记存活对象。
  3. Mixed GC:结合 Eden 区和高垃圾比例的 Old 区回收,优化堆利用率。

G1 的核心在于其区域化设计和优先回收策略,通过最大程度降低垃圾回收对应用的影响,实现低延迟的性能优化。

posted @   Eiffelzero  阅读(144)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
历史上的今天:
2022-12-11 1827. 最少操作使数组递增
点击右上角即可分享
微信分享提示