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都是串行回收;需要停止并发标记,停止增量回收

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

         

7.2.2 计算对象的新地址

7.2.3 更新引用对象的地址

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

  

7.2.4 移动对象完成压缩

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

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

7.2.5 后处理

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

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

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

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

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

7.3 并行FGC

      

7.3.1 并行标记

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

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

7.3.2 计算对象的新地址

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

7.3.3 更新引用对象的地址

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

7.3.4 移动对象完成压缩

7.3.5 后处理 

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

  

发布了331 篇原创文章 · 获赞 1 · 访问量 3487

猜你喜欢

转载自blog.csdn.net/kuaipao19950507/article/details/103939963