G1垃圾回收器简介及回收过程

2023-11-20

一.什么是G1
同CMS一样,G1也是关注停顿时间,不过它是可控的,它被设计用来取代CMS,因为它是空间整理所以没有CMS那么严重的空间碎片问题,同时提供可控的停顿时间。

特性:
1.G1不同于之前的那些垃圾收集器分为连续的年轻代,老年代和永久代,而是分区(region),它将堆分为大大小小的区域(通常约为2048个),每个区域就是eden,survivor,old
2.一般优先回收包含垃圾最多的区域,所以叫Garbage-First(G1)
3.之前的垃圾收集器要么是新生代,要么是老年代,而G1兼顾年轻代和老年代
4.可控性:因为G1可以选择回收部分区域,所以可以做到停顿时间的可控性
可以看到G1的堆结构,是分为一个一个的区
在这里插入图片描述

几个名词介绍
Remembered Sets:每个区都有一个 RSet,用于记录进入该区块的对象引用(如区块 A 中的对象引用了区块 B,区块 B 的 Rset 需要记录这个信息),可以避免扫描整个区,而只需要扫描Rset就行,它用于实现收集过程的并行化以及使得区块能进行独立收集。总体上 Remembered Sets 消耗的内存小于 5%。

Collection Sets: GC中待回收的region的集合。CSet中可能存放着各个分代的Region。CSet中的存活对象会在gc中被移动(复制)。GC后CSet中的region会成为可用分区。

Card Table Java虚拟机用了一个叫做CardTable(卡表)的数据结构来**标记老年代的某一块内存区域中的对象是否持有新生代对象的引用,**卡表的数量取决于老年代的大小和每张卡对应的内存大小,每张卡在卡表中对应一个比特位,当老年代中的某个对象持有了新生代对象的引用时,JVM就把这个对象对应的Card所在的位置标记为dirty(bit位设置为1),这样在Minor GC时就不用扫描整个老年代,而是扫描Card为Dirty对应的那些内存区域。

Humongous region: 是G1中存放巨型对象的分区,巨型对象是指占用了region容量的50%以上的一个对象,如果一个H区装不下一个巨型对象,则会通过连续的若干H分区来存储。因为巨型对象的转移会影响GC效率,所以并发标记阶段发现巨型对象不再存活时,会将其直接回收。ygc也会在某些情况下对巨型对象进行回收。

TLAB(Thread Local Allocation Buffer)本地线程缓冲区: 由于对象一般分配在堆上,而堆是线程共用的,因此可能会有多个线程在堆上申请空间,而每一次的对象分配都必须线程同步,会使分配的效率下降。所以在线程初始化时,同时也会在eden区申请一块指定大小的内存,只给当前线程使用,这样每个线程都单独拥有一个空间,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。

栈上分配: 对于那些线程私有对象(指不可能被其他线程访问的对象)可以将它们打散分配在栈上,而不是分配在堆上,这样就不需要GC了,随着线程的销毁而回收。栈空间小,对于大对象无法实现栈上分配。栈上分配依赖于逃逸分析和标量替换 。

Snapshot-At-The-Beginning(SATB): SATB是在G1 GC在并发标记阶段使用的增量式的标记算法。SATB可以理解成在GC开始之前对堆内存里的对象做一次快照,此时活的对象就认为是活的,从而形成一个对象图

二.G1的垃圾回收过程
G1的垃圾回收过程可能包含4部分:
1.新生代GC
2.并发标记周期
3.混合回收
4.Full GC

1.新生代GC:
和其他垃圾收集器差不多,回收eden区,转移survivor区或者晋升年老的。区别是会动态调整新生代大小,基于历史ygc信息和-XX:MaxGCPauseMillis设置的停顿时间。

2.并发标记周期:(和CMS有点类似)主要是标记可回收对象,回收掉完全空闲的区域,过程:

  • 初始标记:标记从根节点可直接到达对象,会伴随一次ygc,STW
  • 根区域扫描:因为已经进行了ygc,所以只有survivor区有对象,扫描survivor区到老年代的引用(不能有ygc,必须等结束才行, 因为ygc会导致survivor区变化)
  • 并发标记:扫描并查找整个堆的存活对象,做好标记(可ygc,会中断标记过程)
  • 重新标记:STW,使用SATB,会在标记之初为存活对象创建一个快照,加快重新标记的速度
  • 独占清理:计算各个区域存活对象和回收比例并排序,识别可供混合回收的区域,更新RemeberedSet,该阶段给需要混合回收的区域做了标记,STW
  • 并发清理:识别并清理完全空闲的区域

3.混合回收
并发标记周期,虽然有部分对象回收,但是总体上说,回收的比例是比较低的。
混合回收不仅进行ygc,而且会回收之前标记出来垃圾最多的区域

4.Full GC
在混合回收过程中,当内存不足时也会触发Full GC
①.concurrent mode failure
②.大对象分配失败
③.晋升失败

三.G1 GC实例

参数设置
-Xms10M -Xmx10M -Xmn3m -XX:+PrintGCDetails -XX:+UseG1GC
 -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
import java.util.ArrayList;

public class TestCMSGC {
    private static byte[] mem = new byte[1024 * 1024 *3];
    public static void main(String[] args) {
        ArrayList<byte[]> arrayList = new ArrayList<>();
           for(;;)
           arrayList.add(mem);
    }
}

ygc日志:

[GC pause (G1 Humongous Allocation) (young) (initial-mark), 0.0017438 secs]
   [Parallel Time: 1.5 ms, GC Workers: 6]
      [GC Worker Start (ms): Min: 104.7, Avg: 104.9, Max: 105.2, Diff: 0.4]
      [Ext Root Scanning (ms): Min: 0.4, Avg: 0.5, Max: 1.0, Diff: 0.6, Sum: 3.1]
      [Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
         [Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0]
      [Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
      [Object Copy (ms): Min: 0.0, Avg: 0.7, Max: 0.9, Diff: 0.9, Sum: 4.2]
      [Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.1, Diff: 0.1, Sum: 0.2]
         [Termination Attempts: Min: 1, Avg: 45.2, Max: 101, Diff: 100, Sum: 271]
      [GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.1]
      [GC Worker Total (ms): Min: 1.0, Avg: 1.3, Max: 1.4, Diff: 0.4, Sum: 7.6]
      [GC Worker End (ms): Min: 106.2, Avg: 106.2, Max: 106.2, Diff: 0.0]
   [Code Root Fixup: 0.0 ms]
   [Code Root Purge: 0.0 ms]
   [Clear CT: 0.0 ms]
   [Other: 0.2 ms]
      [Choose CSet: 0.0 ms]
      [Ref Proc: 0.1 ms]
      [Ref Enq: 0.0 ms]
      [Redirty Cards: 0.0 ms]
      [Humongous Register: 0.0 ms]
      [Humongous Reclaim: 0.0 ms]
      [Free CSet: 0.0 ms]
   [Eden: 3072.0K(3072.0K)->0.0B(2048.0K) Survivors: 0.0B->1024.0K Heap: 6000.1K(10.0M)->4152.0K(10.0M)]
Parallel Time: 1.5 ms 所有GC线程的花费时间,1.6毫秒
GC Worker Start  表示这里6个GC线程启动时间
Ext Root Scanning  根扫描时间
Update RS 更新记忆集,Remembered Sets:每个区块都有一个 RSet,用于记录进入该区块的对象引用(如区块 A 中的对象引用了区块 B,区块 B 的 Rset 需要记录这个信息),可以避免扫描整个区,而只需要扫描Rset就行,它用于实现收集过程的并行化以及使得区块能进行独立收集。
Scan RS 扫描RS时间
Object Copy  在正式回收前,G1会将存活对象放在其他区域,因此需要对象复制
Termination 线程花在终止阶段的耗时,GC线程终止前,会检查还有没对象没处理完,如果没处理完,请求终止的GC线程会去帮助完成。Termination Attempts 表示每个工作线程尝试终止的次数
GC Worker Other  GC线程哈在其他任务的耗时
GC Worker Total  GC耗时
GC Worker End   单个GC线程结束的时间
Other 其他几个任务的耗时
Choose CSet  
Ref Proc  处理弱引用,软引用的时间
Ref Enq   弱引用,软引用的入队时间
Redirty Cards  重新脏化卡表
Humongous Register,Humongous Reclaim   主要是对巨型对象回收的信息,youngGC阶段会对RSet中有引用的短命的巨型对象进行回收,巨型对象会直接回收而不需要进行转移(转移代价巨大,也没必要)

Free CSet  是否被回收的Cset区域

混合标记周期日志:
可以看到在ygc完成后就开始并发标记周期

[GC pause (G1 Humongous Allocation) (young) (initial-mark), 0.0010437 secs]
[Parallel Time: 0.8 ms, GC Workers: 6]
[GC Worker Start (ms): Min: 77.5, Avg: 77.6, Max: 77.8, Diff: 0.3]
[Ext Root Scanning (ms): Min: 0.0, Avg: 0.3, Max: 0.7, Diff: 0.7, Sum: 1.9]
[Update RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Processed Buffers: Min: 0, Avg: 0.0, Max: 0, Diff: 0, Sum: 0]
[Scan RS (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Code Root Scanning (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.0]
[Object Copy (ms): Min: 0.0, Avg: 0.3, Max: 0.4, Diff: 0.4, Sum: 2.1]
[Termination (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.2]
[Termination Attempts: Min: 1, Avg: 2.5, Max: 5, Diff: 4, Sum: 15]
[GC Worker Other (ms): Min: 0.0, Avg: 0.0, Max: 0.0, Diff: 0.0, Sum: 0.2]
[GC Worker Total (ms): Min: 0.5, Avg: 0.7, Max: 0.8, Diff: 0.3, Sum: 4.4]
[GC Worker End (ms): Min: 78.3, Avg: 78.3, Max: 78.3, Diff: 0.0]
[Code Root Fixup: 0.0 ms]
[Code Root Purge: 0.0 ms]
[Clear CT: 0.0 ms]
[Other: 0.2 ms]
[Choose CSet: 0.0 ms]
[Ref Proc: 0.1 ms]
[Ref Enq: 0.0 ms]
[Redirty Cards: 0.0 ms]
[Humongous Register: 0.0 ms]
[Humongous Reclaim: 0.0 ms]
[Free CSet: 0.0 ms]
[Eden: 2048.0K(3072.0K)->0.0B(2048.0K) Survivors: 0.0B->1024.0K Heap: 1621.2K(10.0M)->704.1K(10.0M)]
[Times: user=0.00 sys=0.00, real=0.00 secs]
可以看到在上面ygc完成后就开始并发标记周期,依次是根扫描,并发标记,重新标记,独占清理,并发清理
[GC concurrent-root-region-scan-start]
[GC concurrent-root-region-scan-end, 0.0003243 secs]
[GC concurrent-mark-start]
[GC concurrent-mark-end, 0.0000137 secs]
[GC remark [Finalize Marking, 0.0000911 secs] [GC ref-proc, 0.0000384 secs] [Unloading, 0.0005454 secs], 0.0007483 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
[GC cleanup 6904K->6904K(10M), 0.0001752 secs]
[Times: user=0.00 sys=0.00, real=0.00 secs]
[GC concurrent-cleanup-start]
[GC concurrent-cleanup-end, 0.0002721]

更多G1 GC日志可以参考这个:
https://www.cnblogs.com/javaadu/p/11220234.html

四.参数设置

-XX:+UseG1GC

使用 G1 收集器

-XX:MaxGCPauseMillis=200
-XX:G1MixedGCCountTarget:一次全局并发标记之后,后续最多执行的MixedGC次数。 默认值是8.

指定目标停顿时间,默认值 200 毫秒。

在设置 -XX:MaxGCPauseMillis 值的时候,不要指定为平均时间,而应该指定为满足 90% 的停顿在这个时间之内。记住,停顿时间目标是我们的目标,不是每次都一定能满足的。

-XX:InitiatingHeapOccupancyPercent=45

整堆使用达到这个比例后,触发并发标记周期,默认 45%。

如果要降低晋升失败的话,通常可以调整这个数值,使得并发周期提前进行

-XX:NewRatio=n

老年代/年轻代,默认值 2,即 1/3 的年轻代,2/3 的老年代

不要设置年轻代为固定大小,否则:

G1 不再需要满足我们的停顿时间目标
不能再按需扩容或缩容年轻代大小
-XX:SurvivorRatio=n

Eden/Survivor,默认值 8,这个和其他分代收集器是一样的

-XX:MaxTenuringThreshold =n

从年轻代晋升到老年代的年龄阈值,也是和其他分代收集器一样的

-XX:ParallelGCThreads=n

并行收集时候的垃圾收集线程数

-XX:ConcGCThreads=n

并发标记阶段的垃圾收集线程数

增加这个值可以让并发标记更快完成,如果没有指定这个值,JVM 会通过以下公式计算得到:

ConcGCThreads=(ParallelGCThreads + 2) / 4^3

-XX:G1ReservePercent=n

堆内存的预留空间百分比,默认 10,用于降低晋升失败的风险,即默认地会将 10% 的堆内存预留下来。

-XX:G1HeapRegionSize=n

每一个 region 的大小,默认值为根据堆大小计算出来,取值 1MB~32MB,这个我们通常指定整堆大小就好了。
-XX:G1MixedGCCountTarget
一次全局并发标记之后,后续最多执行的MixedGC次数。 默认值是8.

参考:
https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html
https://javadoop.com/post/g1
https://www.jianshu.com/p/9edcbc4bcb8b?from=singlemessage
https://blog.csdn.net/lijingyao8206/article/details/80566384
https://blog.csdn.net/lijingyao8206/article/details/80513383
https://ezlippi.com/blog/2018/01/jvm-card-table-turning.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

G1垃圾回收器简介及回收过程 的相关文章

随机推荐

  • 故障分析系列(01) —— scrapy爬虫速度突然变慢原因分析

    故障分析系列 01 scrapy爬虫速度突然变慢原因分析 1 问题背景 在所有环境都没变的情况下 scrapy爬虫每天能爬取的数据量从3月5号开始急剧减少 后面几天数据量也是越来越少 2 环境 系统 win7 python 3 6 1 sc
  • visual studio:是否统一换行符 提示弹窗是否显示

    工具 选项 环境 文档 加载时检查一致的行尾
  • 推荐一篇详细的Nginx 配置清单

    Nginx 是一个高性能的 HTTP 和反向代理 web 服务器 同时也提供了 IMAP POP3 SMTP 服务 其因丰富的功能集 稳定性 示例配置文件和低系统资源的消耗受到了开发者的欢迎 本文 我们总结了一些常用的 Nginx 配置代码
  • Obsidian 入门使用手册

    文章目录 一 Obsidian 入门 1 1 什么是 Obsidian 1 2 安装 Obsidian 二 Obsidian 配置 2 1 创建第一个笔记 2 2 设置界面语言使用中文 2 3 主题 三 小结 一 Obsidian 入门 1
  • VScode配置文档

    vscode配置 常用插件 View In Browser 预览页面 ctrl F1 vscode icons 侧栏的图标 对于一个有视觉强迫症的人是必须要的 HTML Snippets 支持HTML5的标签提示 JS CSS HTML F
  • 泰凌微 IDE使用心得

    Telink IDE 1 5 这可能是我用过最难用的IDE 没有之一
  • ARL资产侦察灯塔系统搭建及使用

    ARL资产侦察灯塔系统搭建及使用 ARL Asset Reconnaissance Lighthouse 资产侦查灯塔旨在快速发现并整理企业外网资产并为资产构建基础数据库 无需登录凭证或特殊访问即可主动发现并识别资产 让甲方安全团队或者渗透
  • 微机原理:汽车速度控制系统的设计与实现

    一 设计内容 汽车速度控制系统 在自行设计接口板的按键转换汽车的挡位 发光二极管显示挡位 数码管显示汽车的速度 加速控制 拨动对应的档位再拨动加速开关 数码管显示速度递增至99 加速要与档位匹配 若不匹配则 加速失效 减速控制 拨动减速开关
  • 学习DOM

    DOM的概述 DOM document object model 文档对象模型 顾名思义他就是用于操作对应的文档的 也就是操作你写的html文档 DOM是一个遵从文档流的语句 所以他是同步机制 DOM的分类 document dom操作中最
  • mybatis异常:nested exception is org.apache.ibatis.builder.BuilderException

    这里我使用的是Mybatis plus然后报的异常 接口如下 xml如下 本来以为一切正常却忽略了接收参数的实体参数名字 也就是接受参数名和xml当中的参数名不一致导致异常 其次是接参里面并没有这几个参数 以至于他也会报这种错误的
  • Python GUI案例之看图猜成语开发(第二篇)

    Python GUI案例之看图猜成语 第二篇 前言 看图猜成语小程序开发 第二篇 游戏选择模式页面 游戏训练模式页面 Python GUI案例之看图猜成语开发 第一篇 Python GUI案例之看图猜成语开发 第三篇 Python GUI案
  • QString转const char*

    QString str hello world 转成const char const char arr str toStdString c str const char arr str toLatin1 constData toUtf8 转
  • [从零开始学习FPGA编程-28]:进阶篇 - 基本组合电路-奇偶校验生成器(Verilog语言版本)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 目录 第1章 奇偶校验生成器 1 1 什么是奇校验 1 2 Verilog语言描述
  • devtools安装_R语言入门之R包的安装

    R语言是一个强大的数据分析工具 其强大之处在于有各种各样的R包帮助其实现各种各样的功能 通常来说 R包的安装主要有四种方法 包括 1 从R语言官网上直接下载相关R包并安装 2 从Bioconductor上下载R包并安装 3 从Github上
  • 华为OD机试真题2022(JavaScript)

    华为OD机试真题题库已换 华为OD机试真题2023 JavaScript 本栏有100 道算法题 并提供正确解法 JavaScript 和解题思路 保证都是华为机试真题 非练习题 大概率会考到原题 大家有什么问题可以留言探讨和交流 华为机试
  • Tomcat 系统架构与设计模式之工作原理篇

    本文以 Tomcat 5 为基础 也兼顾最新的 Tomcat 6 和 Tomcat 4 Tomcat 的基本设计思路和架构是具有一定连续性的 Tomcat 总体结构 Tomcat 的结构很复杂 但是 Tomcat 也非常的模块化 找到了 T
  • MySQL 5.5.62下载、安装与卸载详细步骤

    目录 下载地址 安装过程 测试安装 卸载过程 下载地址 安装包我传到了CSDN 下载不需要积分 是从官网下载上传的 可以放心使用 CSDN下载地址 mysql 5 5 62 winx64 msi 官网下载地址 地址 安装过程 双击安装包打开
  • 计算机网络笔记Part2 物理层(Physical Layer)

    计算机网络笔记Part2 物理层 Physical Layer 一 物理层基本概念 二 数据通信 1 一个数据通信例子 2 相关术语 3 三种通讯方式 4 两种数据传输方式 5 码元 Symbol 波特 Baud 速率 带宽 Band Wi
  • 创建自定义的archetype(项目模板)

    一 archetype简介 Archetype是一个Maven项目的模板工具包 它定义了一类项目的基本架构 Archetype为开发人员提供了创建Maven项目的模板 同时它也可以根据已有的Maven项目生成参数化的模板 通过archety
  • G1垃圾回收器简介及回收过程

    一 什么是G1 同CMS一样 G1也是关注停顿时间 不过它是可控的 它被设计用来取代CMS 因为它是空间整理所以没有CMS那么严重的空间碎片问题 同时提供可控的停顿时间 特性 1 G1不同于之前的那些垃圾收集器分为连续的年轻代 老年代和永久