G1(Garbage-First)是 Java 中一种面向全堆的垃圾回收器,旨在实现低延迟和高吞吐量的垃圾回收。G1 将堆内存划分为多个大小相等的区域(Region),每个区域可以是 Eden、Survivor 或 Old 区。G1 的垃圾回收流程分为以下几个主要阶段:
1. 年轻代垃圾回收(Young GC)
年轻代垃圾回收是 G1 中最频繁的垃圾回收操作,主要回收 Eden 区和 Survivor 区中的对象。
流程:
- 初始标记(Initial Mark):
- 这是一个 STW(Stop-The-World)阶段,标记从 GC Roots 直接可达的对象。
- 初始标记阶段通常会与年轻代垃圾回收一起执行,以减少额外的停顿时间。
- 根区域扫描(Root Region Scanning):
- 扫描 Survivor 区中直接引用老年代对象的区域。
- 这一阶段是并发的,不会暂停应用线程。
- 并发标记(Concurrent Marking):
- 并发标记阶段会遍历整个堆,标记所有存活对象。
- 这一阶段是并发的,应用线程可以继续运行。
- 最终标记(Final Marking):
- 这是一个 STW 阶段,处理在并发标记期间遗漏的对象。
- G1 使用 SATB(Snapshot-At-The-Beginning)算法,确保所有存活对象都被正确标记。
- 清理(Cleanup):
- 清理阶段会统计每个区域的存活对象,并选择回收价值最高的区域进行回收。
- 这一阶段是部分并发的,可能会产生浮动垃圾(Floating Garbage)。
2. 混合垃圾回收(Mixed GC)
混合垃圾回收是 G1 中用于回收老年代区域的垃圾回收操作。它会在年轻代垃圾回收之后执行,回收一部分老年代区域。
流程:
- 初始标记(Initial Mark):
- 与年轻代垃圾回收的初始标记阶段相同,标记从 GC Roots 直接可达的对象。
- 并发标记(Concurrent Marking):
- 并发标记阶段会遍历整个堆,标记所有存活对象。
- 最终标记(Final Marking):
- 处理在并发标记期间遗漏的对象,确保所有存活对象都被正确标记。
- 清理(Cleanup):
- 统计每个区域的存活对象,并选择回收价值最高的区域进行回收。
- 复制/清除(Evacuation):
- 将存活对象从被回收的区域复制到新的区域,并清空被回收的区域。
3. 全堆垃圾回收(Full GC)
全堆垃圾回收是 G1 中的一种备用机制,当 G1 无法在预期时间内完成垃圾回收时,会触发 Full GC。Full GC 是单线程的,会导致较长的停顿时间。
流程:
- 标记(Marking):
- 标记所有存活对象。
- 清除(Sweeping):
- 清除所有未被标记的对象。
- 压缩(Compaction):
- 压缩堆内存,减少内存碎片。
G1 垃圾回收流程的总结
阶段 | 年轻代垃圾回收(Young GC) | 混合垃圾回收(Mixed GC) | 全堆垃圾回收(Full GC) |
---|---|---|---|
初始标记 | STW,标记 GC Roots 直接可达的对象 | STW,标记 GC Roots 直接可达的对象 | STW,标记所有存活对象 |
根区域扫描 | 扫描 Survivor 区中引用老年代对象的区域 | 无 | 无 |
并发标记 | 并发标记所有存活对象 | 并发标记所有存活对象 | 无 |
最终标记 | STW,处理遗漏对象 | STW,处理遗漏对象 | 无 |
清理 | 统计存活对象,选择回收区域 | 统计存活对象,选择回收区域 | 无 |
复制/清除 | 将存活对象复制到新区域 | 将存活对象复制到新区域 | 清除未标记对象,压缩堆内存 |
G1 垃圾回收的特点
- 低延迟:通过并发标记和部分并发清理,减少 STW 时间。
- 高吞吐量:通过分区域回收,提高垃圾回收的效率。
- 可预测的停顿时间:通过设置最大停顿时间目标(-XX:MaxGCPauseMillis ),控制垃圾回收的停顿时间。
总结
G1 垃圾回收器的流程包括年轻代垃圾回收、混合垃圾回收和全堆垃圾回收。通过并发标记、SATB 算法和分区域回收,G1 能够在低延迟和高吞吐量之间取得平衡,适用于大内存和多核处理器的应用场景。
THE END
暂无评论内容