• G1回收器介绍


    G1回收器介绍

    Garbage-First (G1)垃圾回收器适用于“CPU多核、大内存”的服务器。它尝试以高概率满足垃圾收集(GC)暂停时间目标,同时实现高吞吐量 。

    G1回收器将heap分成一组大小相等的region(大约2000个),每个region的大小固定在1~32MB(必须为2的幂数)。每个region的内存是物理连续的,不同的region内存物理地址不一定连续,但是同generation的多个region是逻辑连续的。 这就是G1“区域化”。

    一组region被逻辑划分成“young generation(含eden区、survivor区)”、“old generation(含old region,humongous region”。young generation和old generation的内存地址不是固定不变的,会应用的运行,由jvm在Xmx范围动态调整。

    注意:G1中没有survivor0 survivor1之分,只有一个,大小是动态分配的。

    什么是RSets?

    每个Region初始化时,会初始化一个remembered set(已记忆集合),该集合用来记录并跟踪其它Region指向该Region中对象的引用。

    如下:Region1和Region3中有对象引用了Region2的对象,则在Region2的Rset中记录了这些引用。

    在垃圾回收时,根据Rsets即可知道一个region中的对象被哪些region引用,这样可以避免扫描整个堆来找到可以回收的垃圾。

    什么是Csets?

    垃圾回收器计划回收的region集合。

    YoungGC过程?

    步骤1.  选择收集集合(Collection Set),G1会在遵循用户设置的GC暂停时间上限的基础上,选择一个最大年轻代region数,将这个数量的所有年轻代区域作为收集集合。

    步骤2.  根处理(Root Scanning),接下来,需要从GC ROOTS遍历,查找从ROOTS直达到收集集合的对象,移动他们到Survivor区域的同时将他们的引用对象加入标记栈

    步骤3.  RSet扫描(Scan RS),将RSet作为ROOTS遍历,查找可直达到收集集合的对象,移动他们到Survivor区域的同时将他们的引用对象加入标记栈

    步骤4.  移动(Evacuation/Object Copy),遍历上面的标记栈,将栈内的所有所有的对象移动至Survivor区域(其实说是移动,本质上还是复制)

    注意:YoungGC过程中,存活对象copysurvivor区或者old区的过程是需要STW的。

    eden区和survivor区的大小是动态计算的,可能会一直在变动过程中。

    触发条件:当JVM无法将新对象分配到eden区域时,会触发年轻代的垃圾回收(年轻代垃圾回收是完全暂停的,虽然部分过程是并行,但暂停和并行并不冲突)。也会称为“evacuation pause”

    G1回收器回收old generation的标记过程

    • 初始标记阶段(Initial Mark)需要STW。 对于G1,该过程依附在一个正常的Young GC上。 标记survivor区域的GCroots,这些区域可能引用old generation中的对象。
    • GCroots扫描阶段(root scan:扫描initial mark阶段标记出的GC roots关联的survivor区的对象,以及这些对象引用old generation的对象。标记出引用的对象。
    • 并发标记阶段(concurrent mark:在整个heap中标记存活对象(live object)。该过程和应用线程并发执行不需要STW,也可以被young GC打断。
    • 重新标记阶段(remark需要STW。使用'SATB[snapshot-at-the-beginning]'算法再次标记前述几个过程中断开的引用,避免漏标。  <解决了CMS可能的垃圾漏标问题>
    • 清理阶段(cleanup
      1. 统计存活对象,根据设定的目标停顿时间,确定要回收的region。该过程需要STW
      2. 清空Remembered Sets("Rsets")。该过程需要STW
      3. 重置空的region,并将其加到空白列表中。该过程是concurrent的。

    什么是MixedGC?

    mixedGC,即混合GC,针对年轻代和老年代都进行垃圾回收。mixedGC是G1垃圾回收器中特有的概念。

    触发条件:一旦老年代占据堆内存的 45%(-XX:InitiatingHeapOccupancyPercent:设置触发标记周期的 Java 堆占用率阈值,默认值是 45%。),就要触发 Mixed GC的标记周期。

    什么是full gc?

    对整个堆进行回收,包括新生代,老年代、metaspace等。

    触发条件:当mixedGC回收内存的速度无法跟上内存分配的速度,导致老年代也满了,就会进行Full GC对整个堆进行回收。G1中的Full GC也而是单线程串行的,而且是全暂停,使用的是标记-整理算法,代价非常高。

    G1回收器引入STW的几种情形?

    1. copy存活对象到新的region时;(如YoungGC,MixedGC)
    2. initial mark过程
    3. remark过程
    4. cleanup的部分动作(确定要清空的region,以及确定下次回收的old generation region的"候选人")

    官方文档:

  • 相关阅读:
    java mysql物联网土壤智能监控web前端+java后台+数据接程序
    第3章业务功能开发(线索关联市场活动,插入数据并查询)
    万字长文解析最常见的数据库恢复算法: ARIES
    stm32 - Cortex
    寻找替代Redmine项目管理工具的常见方案
    类似mac dock的tab切换组件
    ICV报告: ADAS SoC市场规模将在2024年迎来较大突破
    String长度限制?
    常见面试题集锦
    Redis常用命令
  • 原文地址:https://blog.csdn.net/zpsimon/article/details/126759766