• 关于 G1(Garbage First)垃圾收集器


    G1收集器

    概念

    G1(Garbage First)是一款主要面向服务端应用的垃圾收集器,JDK 9发布之日,G1宣告取代ParallelScavenge加Parallel Old组合,成为服务端模式下的默认垃圾收集器,而CMS则沦落至被声明为不推荐使用(Deprecate)的收集器。

    G1收集器是垃圾收集器技术发展历史上的里程碑式的成果,它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式。

    设计思路

    虽然G1也仍是遵循分代收集理论设计的,但其堆内存的布局与其他收集器有非常明显的差异:

    • G1不再坚持固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间

    收集器能够对扮演不同角色的Region采用不同的策略去处理,这样无论是新创建的对象还是已经存活了一段时间、熬过多次收集的旧对象都能获取很好的收集效果

    设计原理

    Region中还有一类特殊的Humongous区域,专门用来存储大对象。G1认为只要大小超过了一个Region容量一半的对象即可判定为大对象

    每个Region的大小可以通过参数 -XX:G1HeapRegionSize设定,取值范围为1MB~32MB,且应为2的N次幂。

    而对于那些超过了整个Region容量的超级大对象,将会被存放在N个连续的 Humongous Region 之中,G1的大多数行为都把 Humongous Region 作为老年代的一部分来进行看待

    如下图所示:

    在这里插入图片描述

    虽然G1仍然保留新生代和老年代的概念,但新生代和老年代不再是固定的了,它们都是一系列区域(不需要连续)的动态集合。

    G1收集器之所以能建立可预测的停顿时间模型,是因为它将Region作为单次回收的最小单元,即每次收集到的内存空间都是Region大小的整数倍,这样可以有计划地避免在整个Java堆中进行全区域的垃圾收集。

    更具体的处理思路是让G1收集器去跟踪各个Region里面的垃圾堆积的“价值”大小,价值即回收所获得的空间大小以及回收所需时间的经验值,然后在后台维护一个优先级列表,每次根据用户设定允许的收集停顿时间(使用参数-XX:MaxGCPauseMillis指定,默认值是200毫秒),优先处理回收价值收益最大的那些Region,这也就是“Garbage First”名字的由来。这种使用Region划分内存空间,以及具有优先级的区域回收方式,保证了G1收集器在有限的时间内获取尽可能高的收集效率。

    执行步骤:

    如果我们不去计算用户线程运行过程中的动作,G1收集器的运作过程大致可划分为以下四个步骤:

    • 初始标记: 仅仅是标记一些GC Roots能直接关联到的对象,并且修改TAMS指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新的对象。
    • 并发标记: 从GC Roots开始对堆中对象进行可达性分析,递归扫描整个堆里的对象图,找出要回收的对象,与用户线程并发执行。
    • 最终标记: 对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的SATB记录。
    • 筛选回收: 负责更新Region的统计数量,对各个Region进行回收价值和成本排序,根据用户期望的停顿时间制定回收计划,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧的Region的全部空间。

    下面是G1收集器的运行示意图:
    在这里插入图片描述

  • 相关阅读:
    电力配电机房监控方案
    CSS属性 - display
    从语法到AI率:用ChatGPT润色论文的3个误区
    playwright 一些方法解决cloudflare防护页的问题
    Acwing刷题
    网络代理技术与安全防护
    Python 关于函数的使用
    [Linux]基本指令(二)
    理论和实践详解RabbitMQ优先级队列(priority queues)(带测试样例及分析)
    .NET 序列化枚举为字符串
  • 原文地址:https://blog.csdn.net/weixin_45525272/article/details/126475313