• 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的"候选人")

    官方文档:

  • 相关阅读:
    PIE-engine 教程 ——影像集合的使用map()映射函数(北京市NDVI计算)
    Halcon的相机内参外参的标定
    蒙特卡洛树搜索方法介绍——后台规划(background planning)与决策时规划(decision-time planning)
    【算法4.2】约数(完结)
    技术分享活动
    亚马逊买家号怎么注册?批量注册账号需要准备什么?
    机器学习笔记之EM算法(四)广义EM
    C++ Reference: Standard C++ Library reference: C Library: cstdlib: wctomb
    4.0 SDK Workshop 纪实:一起体验多人、多屏幕共享新功能
    2023年8月国产数据库大事记-墨天轮
  • 原文地址:https://blog.csdn.net/zpsimon/article/details/126759766