G1数据结构

张开发
2026/4/20 1:30:36 15 分钟阅读

分享文章

G1数据结构
‌G1垃圾回收算法的内部结构‌以“化整为零”的分区思想为核心将整个Java堆划分为多个大小相等的独立区域Region每个Region大小通常为1~32MB2的幂次方由JVM根据堆大小自动设定 。这种结构打破了传统垃圾回收器对堆内存的固定分代布局实现了更灵活、高效的内存管理。一、RegionG1的基本单位G1将堆内存划分为‌多个固定大小的Region‌每个Region在运行时可动态扮演不同角色[E] Eden区‌存放新创建的对象。[S] Survivor区‌存放经过一次Young GC后仍存活的对象。[O] Old区‌存放长期存活或从年轻代晋升的对象。‌[H] Humongous区‌专门用于存储大对象大小超过Region容量一半的对象 。例如在一个4GB堆、Region大小为2MB的配置下任何超过1MB的对象都会被直接分配到Humongous Region中 。这种动态角色分配机制使得G1能根据应用行为灵活调整内存布局避免了传统分代回收器中年轻代与老年代比例固定的僵化问题。二、关键数据结构与机制1. ‌Remembered SetRSet记忆集每个Region都维护一个RSet用于记录‌其他Region中对象对该Region的引用关系‌。在进行年轻代回收Young GC时G1无需扫描整个老年代来判断跨代引用只需扫描RSet中记录的引用即可极大提升了效率 。2. ‌Card Table卡表‌RSet的底层实现依赖于‌卡表Card Table‌。堆内存被划分为若干个512字节的“卡Card”每个卡对应卡表中的一个字节。当发生跨Region引用时相应卡被标记为“脏卡Dirty Card”后续通过扫描脏卡来更新RSet 。可以理解为‌Card Table是RSet的数据来源RSet是G1实现高效跨代引用处理的核心机制‌。3. ‌SATBSnapshot-At-The-Beginning在并发标记阶段为保证标记准确性G1采用SATB算法。它在标记开始时记录堆的逻辑快照任何在并发期间被修改或删除的对象引用都会通过写屏障Write Barrier记录到队列中供最终标记阶段处理防止漏标 。‌4. ‌TAMSTop at Mark Start指针为支持并发标记期间的新对象分配G1为每个Region设置了两个TAMS指针Previous和Next划分出用于记录并发阶段新分配对象的空间。这些对象默认被视为“已存活”不参与本次标记过程 。三、回收流程与阶段划分G1的回收周期主要包括以下阶段1‌. Young GC‌当Eden区满时触发STW暂停复制存活对象到Survivor或Old区。‌2. 并发标记Concurrent Marking‌当堆占用达到阈值默认45%时启动标记整个堆的存活对象。‌3. Mixed GC‌在并发标记完成后优先回收垃圾比例高的Region包括部分老年代。4‌. Full GC‌极端情况下如空间不足或碎片严重触发单线程执行应尽量避免

更多文章