zoukankan      html  css  js  c++  java
  • G1垃圾收集器角色划分与重要概念详解【纯理论】

    继续接着上一次【https://www.cnblogs.com/webor2006/p/11129326.html】对G1进行理论化的学习,上一次学到了G1收集器的堆结构,回忆下:

    接着继续对它进行了解:

    G1收集器堆结构:

    • G1使用了gc停顿可预测的模型,来满足用户设定的gc停顿时间,根据用户设定的目标时间,G1会自动地选择哪些region要清除,一次清除多少个region。
    • G1从多个region中复制存活的对象,然后集中放入一个region中,同时整理、清除内存(copying收集算法)。

    G1 vs CMS:

    • 对比使用mark-sweep的CMS,G1使用的copying算法不会造成内存碎片;
    • 对比Parallel Scavenge(基于copying)、Parallel Old收集器(基于mark-compact-sweep),Parallel会对整个区域做整理导致gc停顿会比较长,而G1只是特定地整理几个region。
    • G1并非一个实时的收集器,与parallel Scavenge一样,对gc停顿时间的设置并不绝对生效,只是G1有较高的几率保证不超过设定的gc停顿时间。与之前的gc收集器对比,G1会根据用户设定的gc停顿时间,智能评估哪几个region需要被回收可以满足用户的设定。

    G1重要概念:

    • 分区(Region):G1采取了不同的策略来解决并行、串行和CMS收集器的碎片、暂停时间不可控等问题-----G1将整个堆分成相同大小的分区(Region),再来回顾一下图:
    • 每个分区都可能是年轻代也可能是老年代,但是在同一时刻只能属于某个代。年轻代、幸存区、老年代这些概念还存在,成为逻辑上的概念,这样方便复用之前分代框架的逻辑。 

    • 在物理上不需要连续,则带来了额外的好处-------有的分区内垃圾对象特别多,有的分区内垃圾对象很少,G1会优先回收垃圾对象特别多的分区,这样可以花费较少的时间来回收这些分区的垃圾,这也就是G1名字的由来,既首先收集垃圾最多的分区
    • 依然是在新生代满了的时候,对整个新生代进行回收------整个新生代中的对象,要么被回收、要么晋升,至于新生代也采取分区机制的原因,则是因为这样跟老年代的策略统一,方便调整代的大小
    • G1还是一种带压缩的收集器,在回收老年代的分区时,是将存活的对象从一个分区拷贝到另一个可用分区,这个拷贝的过程就实现了局部的压缩。
    • 收集集合(CSet):一组可被回收的分区的集合。在CSet中存活的数据会在GC过程中被移动到另一个可用分区,CSet中的分区可以来自eden空间、survivor空间、或者老年代。比如说这俩个区域要被回收则就可以称之为CSet:
    • 已记忆集合(RSet):RSet记录了其它Region中的对象引用本Region中对象的关系,属于points-into结构(谁引用了我的对象)。RSet的价值在于使得垃圾收集器不需要扫描整个堆找到谁引用了当前分区中的对象,只需要扫描RSet既可。
      这概念有点绕,因为region与region之间的对象是可以相互引用的,拿图来说:

      这就出现了RSet,专门用来记录谁引用了我。

    • 下面来看图说明:Region1和Region3中的对象都引用了Region2中的对象,因此在Region2的RSet中记录了这两个引用。

      可以看到,对于每一个Region都会有一个RSet。

    • G1 GC是在points-out【言外之意就是指向别人的关系】的card table之上再加了一层结构来构成points-into RSet:每个region会记录下到底哪些别的region有指向自己的指针,而这些指针分别在哪些card的范围内。
    • 这个Rset其实是一个hash table,key是别的region的起始地址,value是一个集合,里面的元素是card table的index。举例来说,如果region A的RSet里有一项的key是region B,value里有index为1234的card,它的意思就是region B的一个card里有引用指向region A。所以对region A来说,该RSet记录的是points-into的关系;而card table仍然记录了points-out的关系。
    • Snapshot-The-Beginning(SATB):SATB是G1 GC在并发标记阶段使用的增量式的标记算法。
    • 并发标记是并发多线程的,但并发线程在同一时刻只扫描一个分区。
  • 相关阅读:
    【java】对象赋值给另一个对象
    spring boot系列(五)spring boot 配置spring data jpa (查询方法)
    Spring Data JPA 查询
    Spring Data JPA 介绍
    OpenID简介
    OAUTH协议介绍
    URL encoding(URL编码)
    RESTful 介绍
    spring boot系列(四)spring boot 配置spring data jpa (保存修改删除方法)
    spring boot 启动报 java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle 错误
  • 原文地址:https://www.cnblogs.com/webor2006/p/11129572.html
Copyright © 2011-2022 走看看