JVM G1源码分析和调优书 阅读笔记 第7章 Full GC

对象分配失败,就会进入到Evac失败过程,在GC日志详情中会打印相关信息

1.处理失败

2.再次尝试分配,仍然不成功,进行Full GC

7.1 Evac失败

   把对象放入到Evac失败栈;直接更新对象的RSet,不需要对已复制的对象做额外回收之类的处理

检查是否有指向自己的指针,如果有,就代表发生了复制失败。需要删除指针,恢复对象头

  1. 把这个分配失败的对象,放入到特殊的dirty card队列中

  2.执行Redirty重构整个RSet,确保引用的正确性

  7.2  FGC 

         JDK10之前,FGC都是串行回收;需要停止并发标记,停止增量回收

         串行回收采用标记清除算法

         JVM G1源码分析和调优书 阅读笔记 第7章 Full GC

JVM G1源码分析和调优书 阅读笔记 第7章 Full GC

JVM G1源码分析和调优书 阅读笔记 第7章 Full GC

7.2.2 计算对象的新地址

JVM G1源码分析和调优书 阅读笔记 第7章 Full GC

7.2.3 更新引用对象的地址

          遍历活跃对象,然后把活跃对象和活跃对象中的引用更新到新位置

  JVM G1源码分析和调优书 阅读笔记 第7章 Full GC

7.2.4 移动对象完成压缩

       遍历必须从前向后依次开始,否则数据会被破坏

       把对象复制到新的地址,然后重新设置对象头,这就是压缩工作

JVM G1源码分析和调优书 阅读笔记 第7章 Full GC

7.2.5 后处理

      分区并没有发生调整,仅仅把已经死亡的对象回收,活跃的对象仍然保留在本分区内

     1.尝试调整整个堆空间的大小,利用期望值和实际值的比较来判断是否需要扩展或者收缩堆空间

     2.遍历堆,重构RSet,否则下一次GC就会丢失根集合,导致回收错误。重构RSet,对每一个分区根据对象的引用关系重构RSet

    3.清除dirty card队列,并把所有的分区都认为是old分区

    4.最后记录各种信息,同时调整YGC的大小

7.3 并行FGC

      JVM G1源码分析和调优书 阅读笔记 第7章 Full GC

7.3.1 并行标记

        类似于并发标记,但是不涉及SATB处理

        并行标记任务主要在G1FullGCMarkTask完成,多个GC从不同的根出发,完成标记,当线程任务完成后,可以尝试窃取别的线程尚未处理完的对象进行标记

7.3.2 计算对象的新地址

         计算新地址可以把这一批分区里面的对象,进行压缩,这样就可能出现完全空闲的分区。

7.3.3 更新引用对象的地址

        从根集合出发遍历活跃对象,然后把活跃对象和活跃对象中的引用都更新到新的位置

7.3.4 移动对象完成压缩

7.3.5 后处理 

        恢复对象头,更新各种信息