Featured image of post JVM_06_G1垃圾收集器原理探索

JVM_06_G1垃圾收集器原理探索

🌏Java工程师 JVM 🎯 这篇文章用于记录 JVM_06_G1垃圾收集器原理探索 相关的学习和总结

🎄G1垃圾收集器原理探索

G1(Garbage-First)是Java虚拟机(JVM)中的一种垃圾收集器。它是一种基于区域(Region)的垃圾收集器,旨在提供更可控的暂停时间和更高的吞吐量。

🍭G1垃圾收集器运行示意图

紫色部分为G1垃圾收集器的工作过程体现

🍭G1垃圾收集器原理分析

🌴 Region(分区)

G1 垃圾收集器通常将堆内存划分为2048个 Region,每个Region的大小可以通过JVM参数进行配置,通常在1MB到32MB之间,且应为2的N次幂。

每个 Region 分区只能是一种角色,Eden区、S区、老年代O区的其中一个,空白区域代表的是未分配的内存。

最后还有个特殊的区域H区(Humongous),专门用于存放巨型对象,如果一个对象的大小超过Region容量的50%以上,G1 就认为这是个巨型对象。在其他垃圾收集器中,这些巨型对象默认会被分配在老年代。

但如果它是一个短期存活的巨型对象,放入老年代就会对垃圾收集器造成负面影响,触发老年代频繁GC。为了解决这个问题,G1划分了一个H区专门存放巨型对象,如果一个H区装不下巨型对象,那么G1会寻找连续的H分区来存储,如果寻找不到连续的H区的话,就不得不启动 Full GC 了。

G1不再要求相同类型的 Region 在物理内存上相邻,而是通过Region的动态分配方式实现逻辑上的连续。

G1收集器通过跟踪Region中的垃圾堆积情况,每次根据设置的垃圾回收时间,回收优先级最高的区域,避免整个新生代或整个老年代的垃圾回收,使得stop the world的时间更短、更可控,同时在有限的时间内可以获得最高的回收效率。

🌴 Remember Set(记忆集)

在串行和并行收集器中,GC时是通过整堆扫描来确定对象是否处于可达路径中。然而G1为了避免STW式的整堆扫描,为每个分区各自分配了一个 RSet(Remembered Set),它内部类似于一个反向指针,记录了其它 Region 对当前 Region 的引用情况。

这样就带来一个极大的好处:回收某个Region时,不需要执行全堆扫描,只需扫描它的 RSet 就可以找到外部引用,来确定引用本分区内的对象是否存活,进而确定本分区内的对象存活情况,而这些引用就是初始标记(initial mark)的根之一(初始标记可见下图 G1垃圾收集器运行示意图)

事实上,并非所有的引用都需要记录在RSet中,如果引用源是本分区的对象,那么就不需要记录在 RSet 中;同时 G1 每次 GC 时,所有的新生代都会被扫描,因此引用源是年轻代的对象,也不需要在RSet中记录;所以最终只需要记录老年代到新生代之间的引用即可。

🌴 Card Table

Card Table是辅助Remembered Set实现的一种数据结构。

它将堆内存划分为一系列固定大小的连续区域,称为“卡”(Card)。每个Card对应堆内存中的一小块连续区域,并且每个Region在逻辑上也被划分为多个Card。当发生跨Region的引用时,G1会在目标Region的Card上进行标记,记录下引用来源的信息。这样,在垃圾收集过程中,G1可以通过扫描目标Region的Card Table来快速确定哪些Region中的对象可能引用了当前Region中的对象。

也就是说,也就是说每一个Region都对应有一个Card Table

🌴 Card Table、Remember Set、Region总结及他们之间的关系

🍩Card Table(卡表):

卡表是G1垃圾收集器用来跟踪堆内存中对象引用关系的数据结构之一。

卡表将堆内存划分成一个个称为"卡"的小块,每个卡通常对应着一定范围的内存空间(例如512字节)。

卡表记录了哪些卡中的对象引用发生了变化,从而帮助G1垃圾收集器快速定位需要更新的对象引用。

🍩Remembered Set(记忆集)

记忆集是G1垃圾收集器用来跟踪跨区域引用关系的数据结构。

记忆集记录了一个区域中的对象引用到其他区域的引用关系。

记忆集实际上是基于卡表的,它存储了每个区域与其他区域之间的引用关系,以便在并发标记阶段快速定位需要处理的对象。

🍩Region(区域): -

区域是G1垃圾收集器管理的最小内存单位,堆内存被划分成多个大小相等的区域。

每个区域都有自己的存活对象集合、垃圾对象集合和其他元数据信息。

G1垃圾收集器在并发标记和清理过程中会针对区域进行操作,以实现精确的垃圾回收。

关系

卡表和记忆集都用于跟踪对象引用关系,但在不同的粒度上。卡表以较小的粒度(卡)跟踪对象引用的变化,而记忆集以区域为单位跟踪跨区域的对象引用关系。

卡表和记忆集是相关联的,卡表中的信息可以帮助记忆集快速定位需要处理的对象引用。

在并发标记阶段,G1垃圾收集器利用卡表和记忆集的信息来高效地标记存活对象,并进行跨区域引用的处理。

三者关系参考下图:

🎄参考链接

[1] JVM垃圾回收详解(重点)

[2] G1 垃圾收集器原理详解

Licensed under CC BY-NC-SA 4.0