G1垃圾回收器

article/2025/9/1 9:32:31

1、最大堆大小

G1管理的最大堆大小为64G。每个Region的大小通过 -XX:G1HeapRegionSize 来设置,大小为 1~32MB ,默认最多可以有2048个Region,G1能管理的最大堆内存是 32MB*2048=64G 。

使用G1垃圾回收器最小堆内存应为 1MB*2048=2GB ,低于此值建议使用其它垃圾回收器。

2、Region大小

Region大小为 1~32MB ,具体取值有1MB、2MB、4MB、8MB、16MB、32MB,Region大小优化与大对象有关,当对象占用内存超过Region的一半时将被视为大对象。

被标记为大对象将不利于垃圾回收。

:如果堆空间(内存)大的时候,每次进行「垃圾回收」都需要对一整块大的区域进行回收,那收集的时间是不好控制的

而划分多个小区域之后,那对这些「小区域」回收就容易控制它的「收集时间」了。

从上一次我们聊CMS回收过程的时候,同样讲到了Minor GC,它是通过「卡表」(cart table)来避免全表扫描老年代的对象

因为Minor GC 是回收年轻代的对象,但如果老年代有对象引用着年轻代,那这些被老年代引用的对象也不能回收掉

同样的,在G1也有这种问题(毕竟是Minor GC)。CMS是卡表,而G1解决「跨代引用」的问题的存储一般叫做RSet

只要记住,RSet这种存储在每个Region都会有,它记录着「其他Region引用了当前Region的对象关系」

对于年轻代的Region,它的RSet 只保存了来自老年代的引用(因为年轻代的没必要存储啊,自己都要做Minor GC了)

对于老年代的 Region 来说,它的 RSet 也只会保存老年代对它的引用(在G1垃圾收集器,老年代回收之前,都会先对年轻代进行回收,所以没必要保存年轻代的引用)

G1 的分代模型

G1 也分为年轻代和年老代,但不是固定划分,而是每个 Region 根据运行情况动态划分。

G1 还有一个特殊的区域叫 Humongous,G1 将超过了一个 Region 容量一半的大对象,都存放在 Humongous 区域中,如果对象超过了 Region 大小,则存放在 N 个连续的 Humongous Region 中。G1 的大多数行为都把 Humongous Region 作为老年代的一部分来进行看待。

TAMS(Top at mark start)

为了保证垃圾回收过程中的同时 Region 也能够被使用,G1 为每一个 Region 设计了两个名为 TAMS 的指针,分别是 Previous TAMS(PTAMS)、Next TAMS(NTAMS)。在并发标记阶段开始前,TAMS 指针指向 Region 内占用内存的边界。在并发标记阶段中,G1 默认指针之上的对象为存活对象不去进行标记,而对象分配时,用户线程直接在指针之上分配。这就保证了扫描行为和对象分配互不干扰。

G1 如何判定 Region 的“价值”

G1 运行期间会收集每个 Region 的价值信息,比如回收耗时、记忆集的脏卡数量等,通过计算得出每个 Region 回收的性价比。G1 的停顿预测模型就是通过这些信息,找出在用户预期时间内获得更高回收收益的 Region 组合。

Remembered Sets

G1 堆中的每一个 Region 都有一份Rememberd Set,也叫RSet,它的作用就是为每一个 Region 记录哪些 Region 对其含有引用。

RSet 的更新需要线程同步处理,由于对象引用变更非常频繁,如果同步写卡表消耗非常大,所以通常会把更新信息存入队列中再异步更新 RSet,这个队列就叫Dirty Card Queue

G1 的垃圾回收过程

当 Eden 中无法分配对象时,触发 Young GC。

当年老代占比到达 45%时,等待下一次 Young GC 时进行并发标记。

并发标记结束后马上执行 Mixed GC。

当 Mixed GC 对内存的清理速度赶不上分配新对象的速度时触发 Full GC,G1 的 Full GC 将使用单线程(JDK11 后改为多线程)执行标记整理算法,所以耗时巨大。

G1 的 Young GC

触发时机

当 JVM 无法在 Eden 区分配对象时。

回收范围

Eden 区和 Survivor 区

运行过程(所有阶段均 STW)

1. 根扫描

将所有 Eden 区中的 GC Root 和 RSet 记录的外部引用作为扫描存活对象的入口。

2. 更新 RSet

通过 Dirty Card Queue 中的 card 更新 RSet,保证 RSet 能准确反应老年代对该 Region 是否存在引用。

3. 处理 RSet

将 Eden 区中被 RSet 指向的对象标记为存活对象。

4. 对象复制

判断存活对象的年龄,如果未达到“阈值”,则复制到一个 Surviver 区中,否则复制到 Old 区中。如果 Surviver 空间不够,则将部分对象直接复制到 Old 区中。

5. 处理引用

处理软引用、弱引用、虚引用等,最终清空全部 Eden 区。这时清理过的内存空间没有内存碎片。

G1 的 Mixed GC

触发时机

年老代占用空间超过整个堆的 45%(可通过参数-XX:InitiatingHeapOccupancyPercent进行设置)

事实上,并不会立刻触发,而且等待下一次 Young GC,同步进行初始标记步骤。

回收范围

被并发标记过的 Region,这些 Region 是 G1 通过价值测算动态选中的。

运行过程

1. 初始标记(Initial Marking)[STW]

标记 GC Roots 直接关联的对象,并修改 TAMS 指针的值。值得注意的是,这一阶段并不单独执行,而是在 Minor GC 时同步完成。所以实际上这个阶段没有额外停顿。

2. 并发标记(Concurrent Marking)

与用户线程并发执行,顺着 GC Root 递归标记。标记完成后,重新扫描 SATB 记录的有引用变动的对象。如果这时发现空的 Region 则直接将其清空。

3. 重新标记(Remark)[STW]

由于并发标记是并发执行,并发标记结束后,仍然存在少量的引用变动的对象,所以在这个阶段可以 STW 来处理这部分遗留的对象。并且开始计算所有 Region 的活跃度。

4. 清理(Clean Up)[STW]

根据用户期望的停顿时间来制定回收计划,选择全部是非存活对象的 Old 区和回收收益较高的 Region 加入回收集。清空记忆集。重置已经被清理的空的 Region(这一步是非 STW 的)。

5. 拷贝(Coping)[STW]

将回收集其中的存活对象复制到空的 Region 中,最后清空这些旧的 Region。

这个阶段的算法和 Young GC 完全一致,但默认分 8 次执行完成(可由参数-XX:G1MixedGCCountTarget 设置)。所以每次清理的回收集包括 Eden 区、Survivor 区和八分之一的 Old 区。低存活度(垃圾多)的 Region 清理的较快,所以会被 G1 优先回收。

混合回收并不一定要进行 8 次。有一个阈值-XX :G1HeapWastePercent(默认值为 10%),意思是允许整个堆内存中有 10%的空间被浪费,意味着如果发现可以回收的垃圾占堆内存的比例低于 10%,则不再进行混合回收。

优点

G1 相比较之前的垃圾回收器最大的变化是通过化整为零的思路,将堆分为若干个小的 Region 来减少 GC 的范围,从而达到“低延迟”的目的。

并且 G1 的垃圾回收过程采用标记复制的算法,避免了空间碎片化的问题。

缺点

1.内存占用较高,由于 G1 分区比 CMS 更多,每个 Region 都需要建立卡表。其中新生代对象变动频繁,又加大了卡表维护的成本。

2.G1 不仅需要通过写前屏障来更新卡表,还需要写后屏障来跟踪并发时的指针变化以实现快照搜索算法(SATB)。这样虽然相比增量更新算法能够减少并发标记和重新标记阶段的消耗,但是用户程序运行时的计算负载就高了。

3.G1 和 CMS 同样具有“并发回收”的能力,所以垃圾回收的速度如果跟不上用户创建新对象的速度,那么就会触发一个 Full GC 来获取更多内存。通常把期望停顿时间设置为一两百毫秒或者两三百毫秒会是比较合理的。

这里要提下的是,在G1还有另一个名词,叫做CSet。

它的全称是 Collection Set,保存了一次GC中「将执行垃圾回收」的Region。CSet中的所有存活对象都会被转移到别的可用Region上

最佳实践

1.不要设置年轻代大小年轻代大小应当由 G1 自行控制,设置为固定值将覆盖暂停时间目标

2.暂停时间目标不要过于严苛 G1 为了 Young GC 能够缩短时间需要减少 Eden 区的个数,那么 Young GC 就会更加频繁。Mixed GC 想要达到停顿目标就需要减少回收的垃圾数量,如果回收速度低于新对象分配速度将引起 Full GC。

3.CMS 和 G1 的选择目前在小内存应用上 CMS 的表现大概率仍然要会优于 G1,而在大内存应用上 G1 则大多能发挥其优势,这个优劣势的 Java 堆容量平衡点通常在 6GB 至 8GB 之间。

7 总结

在 GC 的选择上,同样是“没有银弹”,不同的收集器有着各自的特点和适用场景,即使是 Epsilon 也会在特定场合下发挥作用。我们应针对不同的业务特征和系统情况选择最合适的垃圾回收器,而不是一味求新。

1、堆内存

参数默认值说明优化建议
MaxGCPauseMillis200ms最大停顿时间
G1HeapRegionSize不设置时启发式推断
G1NewSizePercent5新生代最小百分比
G1MaxNewSizePercent60新生代最大百分比

2、新生代内存回收

参数默认值说明优化建议
ParallelGCThreads并行GC线程数,会根据CPU核数推断默认值
MaxTenuringThreshold15从新生代晋升到老年代年龄阈值
SurvivorRatio8Eden和一个Survivor的比例
TargetSurvivorRatio50Survivor区内存使用率,增大该值会降低到老年代概率
+G1EagerReclaimHumongousObjectstrue是否在YGC时回收大对象

3、混合回收

参数默认值说明优化建议
G1MixedGCCountTarget8值越大,收集老年代分区越少
G1OldCSetRegionThresholdPercent10表示一次最多收集10%的分区

https://shipilev.net/talks/devoxx-Nov2017-shenandoah.pdf

什么?面试官问我G1垃圾收集器? - 掘金


http://chatgpt.dhexx.cn/article/UpJ4pSnf.shtml

相关文章

ZGC都出来了,你还不懂G1?

概念 G1(Garbage-First Collector)是一种垃圾回收算法,最早在JDK 6 Update 14中作为实验性功能加入,并在JDK 7 Update 4正式JDK,之后在JDK 9 中成为默认垃圾回收算法,在JDK 10中优化了Full GC性能。 G1是一…

G1详解

一 G1收集器 g1收集器是一个面向服务端的垃圾收集器适用于多核处理器、大内存容量的服务端系统。 它满足短时间gc停顿的同时达到一个较高的吞吐量。 JDK7以上版本适用 “ 先介绍两个概念:吞吐量和响应能力,响应能力和吞吐量是评价一个系统的两个重要指标…

G1垃圾回收器详解

文章目录 前言一、思考问题二、官方文档三、基本介绍四、G1的内存模型五、G1的标记过程六、G1的垃圾回收1、G1过程梳理2、Young GC3、Mixed GC4、Full GC 七、参数介绍八、分析各阶段触发时机根据GC日志分析Young GC的触发时机根据GC日志分析并发标记的触发时机根据GC日志分析M…

G1 GC

G1GC基本概念 G1 GC可以看做是CMS GC的重大升级改造G1 GC的全称是Garbage-First,意为垃圾优先,哪一块的垃圾最多就优先清理他。G1 GC最主要的设计目标是:将STW停顿的时间和分布,变成可预期且可配置的。(默认200ms&…

G1垃圾回收器-----基本知识及原理解析

G1介绍(Garbage first) G1主要面向的是服务端的垃圾回收器。在G1之前,JVM的主要垃圾回收器采用的是物理分代的思想,将内存区域严格的划分成年轻代(young GC)和老年代(major GC)&…

可控硅BT136典型应用电路

1.双向可控硅SCR可根据负载功率大小选择97A6(约1A)、TLC336A(约3A)、BT136-500D(约6A)中的一个,选择原则是触发电流要小于25mA。 2.C4取值在0.1 ~ 0.47uF之间&#xff0c…

全能电子地图实时路况_全能SUV与城市SUV的区别在哪?日产奇骏对比本田皓影

在如今的市场中,越来越多的车企将重点放在SUV车型中,尤其今年大量家用SUV涌入市场,特别是紧凑级SUV将这片市场瓜分的“支离破碎”。即使车型越来越多,市场被瓜分的越来越小,但是在很多消费者心中,几个主流品…

音质卓越颜值在线,五款高人气头戴式HIFI音质蓝牙耳机排名

随着我们生活水平的逐渐提高,我们对科技产品的要求也就越来越高,就拿耳机来说,对于很多上班族或是年轻人耳机绝对是出门或是旅行的必备品之一,没有音乐的路途那绝对是缺少了灵魂,那自然耳机的地位也就越发的重要。无线,音效,小巧,这几个因素也就成为了我们选择耳机的最…

服务器购买及宝塔部署环境说明(阿里云为例)

服务器相关知识 为什么程序员都需要自己的服务器? 1、你作为一个程序员,必须要发部自己的网站和项目! 2、联系Linux的操作。 3、自己的远程仓库、远程数据库、远程tomcat…都可以搭建在服务器上 4、联系,Linux进行任意的环境…

Linux学习一概述和环境搭建(入门概述,环境搭建,走近Linux系统)

此文档学习来自b站遇见狂神说,自己做的学习笔记整合。 狂神说Linux 继续Java全栈开发的Linux,而不是运维级别! 我们为什么要在这个时间学习Linux?Java全栈开发的我们要掌握哪些知识?需要准备什么工作? J…

CK6855M1蓝牙离线语音识别灯控模组使用说明书

CK6855M1蓝牙离线语音识别灯控模组使用说明书 一、功能说明 CK6855M1模块是一款专为灯具照明产品设计的离线蓝牙语音识别模组。模组支持红外遥控接收,支持RGBWY灯控制,支持无极调光,支持AD按键调灯以及音频上下曲的控制,支持5.1…

为什么P2P模式下载的人越多速度越快,为什么P2P伤害机械硬盘

台风来临前的夜晚,有点激动不想睡觉,看了几个电影,日本恐怖片,台风雨夜,非常不错,P2P很流畅,观察IP地址大量也是附近的,江浙沪,难道也都在迎台风看电影? 大家…

伊人在线高清视频 index.php,《天元》“畅音阁”首发飞行技能视频

直面一款网游给人感觉的优异度最大成分中的重中之重就是第一感——“视听”印象。一直以来,游戏音乐以及画面成分的优异华丽与否直接关系到了玩家对于此款游戏的好感度,无可厚非。而《天元》特别针对于此,倾情打造出一篇关于对于其所有“视听…

迅雷跃居全球BT市场第一

据torrentfreak报道,根据早些时候海盗湾公布的一些数据表明,全球BT软件的使用者,大约有三分之一来自中国,而来自美国的仅有8%,迅雷成为全球BitTorrent市场份额最大的客户端。 迅雷本身并不是一个专门使用P2P的BT客户端…

11个资源强大的网站!知乎超20万人强烈推荐,再也不怕资源难找

在我们日常工作学习中难免就需要在网站搜索资料,这时候一定需要一个能够帮你搜索一切你想要的资源,从而为你剩下一大半时间,那么今天为大家整理了11个超级好用的黑科技资源搜索网站,帮你解决因为上网找不到合适的资源而发愁&#…

Linux6.8搭建sftp服务

最近因公司工作需要用到sftp服务器,参考网上各种方法,但被网上各种方法尤其是权限设置问题搞得晕头转向,现在将自己搭建过程总结了一下,提供给大家希望有所帮助。 sftp是Secure FileTransfer Protocol的缩写,安全文件传…

107-161JS

107-161 target事件委托正则表达式捕获exec特性 this指向改变this指向ES6定义变量ES6箭头函数ES6解构赋值ES6展开运算符ES6模块化初识面向对象创建对象构造函数注意问题面向对象的原型ES6-Class面向对象继承ES6继承Aajaxajax同步异步请求方式1ajax的封装回调地狱promise基础语法…

fastjson与net.sf.json区别

在现在的开发当中&#xff0c; 绝大多数引用阿里巴巴的fastjson。 当然net.sf.json同样可以使用。 一、引入com.alibaba.fastjson包 <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson --> <dependency><groupId>com.alibaba</groupId>…

SftpGo:一款高性能的sftp server服务

SftpGo是一款高性能、功能齐全、易用可配置的一款sftp server 服务&#xff0c;基于go开发。目前在linux、macos下均可以稳定运行(windows个人未测试)。数据可以持久化到主流的数据库&#xff0c;诸如Mysql、PostgreSQL、Sqlilte. sftpgo主要组成 服务端主程序: sftpgosever…

SF简易IDC系统V1.0免授权

介绍&#xff1a; 提供官方EP接口&#xff08;可免费无限开通主机和CDN&#xff09; 2.站长可自己上架主机定义金额&#xff0c;更有自定义模式&#xff08;客户自己选择配置&#xff0c;根据配置进行付钱&#xff09; 3.独立支付接口 —————— 源码无后门&#xff0c;免授…