G1垃圾回收器核心工作原理以及整体流程

127 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

G1 ( Garbage­First GC) 就是 把堆切成了很多份区域,有点像类似于ConcurrentHashMap 的分段是的。其他的垃圾回收回收器,都是对某个年代的整体收集。

   它也有 Eden 区和 Survivor 区的概念,只不过它由一小份一小份组成的,且在内存上不是连续的。

   它分配每一个小份区域的大小是固定的,名字叫作小堆区(Region)。小堆区可以是 Eden 区,也可以是 Survivor 区,还可以是 Old 区。所以 G1 的年轻代和老年代的概念都是逻辑上的。

   每一块 Region,大小都是一致的,它的数值是在 1M 到 32M 字节之间的一个 2 的幂值数。

   如果对象太大,一个 Region 放不下的时候,会把该对象放在 Humongous Region(大小超过 Region 50% 的对象,将会在这里分配)。

   在垃圾回收的时候,小堆区的垃圾最多,会被优先收集,这就是G1的由来。

   G1的回收过程分为 分为3种:
1. G1“年轻代”的垃圾回收 -- Minor GC, 它发生在 eden 区满的时候.
1.1 扫描根
可以看做 GC Roots + RSet 记录的其他 Region 的外部引用。
解释 RSet: 是一个空间换时间的数据结构。 可以把当成 Hash,key 是引用的 Region 地址,value 是引用它的对象的卡页集合。
对于年轻代的 Region,它的 RSet 只保存了来自老年代的引用,因为年轻代的回收是针对所有年轻代 Region ,即年轻代 Region 的 RSet 有可能是空的。
对于老年代的 Region,它的 RSet 也只会保存老年代对它的引用,因为老年代回收之前,会先对年轻代进行回收,这时,Eden 区变空了,而在回收过程中会扫描 Survivor 分区,所以也没必要保存来自年轻代的引用。
1.2 更新 RSet
处理 dirty card queue 中的卡页,更新 RSet数据的引用。在此之后,RSet 可以准确的保存老年代对所在的内存分段中对象的引用  

        1.3 处理 RSet 
检测老年代指向Eden的对象,被标记为存活对象

        1.4 复制对象    
采用 Copy 收集算法
1.5 处理引用
处理 Soft、Weak、Phantom、Final、JNI Weak 等引用。结束收集。

   2. 老年代的垃圾收集 ,对所要回收的对象,进行 并发标记,顺带回收一点点对象
当整个堆内存使用达到一定比例(默认是 45%),并发标记阶段就会被启动。这个比例也是可以调整的,通过参数 -XX:InitiatingHeapOccupancyPercent 进行配置。

         2.1 初始标记(Initial Mark)
该过程共用了 Minor GC 的暂停,这是因为它们可以复用 root scan 操作。
2.2 Root 区扫描(Root Region Scan)

2.3 并发标记( Concurrent Mark)
从 GC Roots 开始对 heap 中的对象标记,标记线程与应用程序线程并行执行,并且收集各个 Region 的存活对象信息。 
2.4 重新标记(Remaking)
标记那些在并发标记阶段发生变化的对象
2.5 清理阶段(Cleanup)
该程不需要 STW。若 Region 里全是垃圾,会立马被清除掉。不全是垃圾的 Region,它会在 Mixed GC 阶段,进行收集。

   3. 混合模式垃圾收集, 它是真正的清理,它不止清理年轻代, 还将一部分老年代的区域进行清理。
混合收集过程,不只清理年轻代,还会将一部分老年代区域也加入到 CSet( Collection Set,即收集集合,保存一次 GC 中将执行垃圾回收的区间(Region))。

通过 并发标记(Concurrent Marking) 阶段,已经统计了老年代的垃圾占比。在 Minor GC 之后,如果判断这个占比达到了某个阈值,下次就会触发 Mixed GC。

\

 优化参数:
-XX:MaxGCPauseMillis=10  G1 任意 1 秒的时间内,停顿不得超过 10ms

       -XX:G1HeapRegionSize=1M   设置Region的大小为1M


-XX:InitiatingHeapOccupancyPercent=45  调整并发标记大小,当整个堆内存使用达到一定比例(默认是 45%),触发启动并发标记阶段

       -XX:G1HeapWastePercent  设置 Mixed GC 阈值(默认是堆大小的 5%)