当前位置:网站首页>驾驭一切的垃圾收集器 -- G1
驾驭一切的垃圾收集器 -- G1
2022-06-27 16:54:00 【用户3147702】
1. 引言
上一篇文章中,我们介绍了 CMS 垃圾回收机制的具体回收过程:
我们看到,CMS 的垃圾回收机制下,想要做到性能的调优,超强的耐心与丰富的经验是必不可少的,因为整个回收过程相关的 jvm 参数就有几十个之多,如何才能将 CMS 回收机制调整到最适合当前场景的使用是困扰诸多 java 程序员的一大问题。
出于对上述问题的优化,G1 垃圾回收器诞生了,他旨在让开发人员通过简单的参数实现系统性能的调优:
-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200
- -XX:+UseG1GC 是必须的,它用来告诉 jvm 开启 G1 垃圾收集器
- -Xmx32g 设置了最大堆内存的大小
- -XX:MaxGCPauseMillis 用来设置最大停顿时间
这样配置之后,你就可以使用 G1 垃圾收集器了,相比于 CMS 是不是很轻松呢?
由于 G1 拥有垃圾回收时间的预测机制,因此他可以保证在你设置的最大停顿时间内完成垃圾回收,这可以说是 G1 垃圾回收器最令人惊喜的特性了。
当然,除了上述三个参数,还有几个可选的参数供开发人员配置,但相比于 CMS,仍然无疑是更加容易进行调优的。
那么,G1 垃圾收集器是如何实现的呢?相比于 CMS 他又有哪些优势和不足呢?本文就来详细介绍一下。
2. G1 与内存分区
G1 垃圾回收器的第一篇 paper 在 2004 年发表,到 2012 年终于被加入到 jdk 1.7u4 中,到了 jdk9,G1 已经变成了默认的垃圾收集器,可以参看官方文档:
https://docs.oracle.com/javase/9/gctuning/garbage-first-garbage-collector.htm#JSGCT-GUID-ED3AB6D3-FD9B-4447-9EDF-983ED2F7A573
与传统的分代垃圾回收器不同,G1 不再将堆内存分为预设的年轻代与老年代,而是将堆内存划分为若干不连续但大小相同的区域 -- Region,每个 Region 占据一块连续的虚拟内存地址空间。
如图所示,Region 有四种类型:
- Eden 区 -- 新生代
- Survive 区 -- 幸存区
- Old 区 -- 老年代
- Humongous 区 -- 巨大对象存储区
新生代、幸存区、老年代的定义与 CMS 中并没有明显区别,但 G1 中新增了 Humongous 存储区域,这部分空间用来存储超过 Region 大小一半的超大对象。
默认情况下,G1 会根据堆内存的大小自动设定每个 Region 的大小,我们也可以通过下面的参数设定一个 Region 的大小,取值范围是 1M 到 32M,且必须是 2 的指数:
-XX:G1HeapRegionSize=2M
3. 对象分配策略
既然我们知道了 G1 管理下的内存分区,那么,如果要新创建一个对象,他会被分配到哪个内存区域呢?
G1 对于对象分配有三个级别:
- TLAB(Thread Local Allocation Buffer)线程本地分配缓冲区
- 在 Eden 区进行分配
- 在 Humongous 区进行分配
在 Eden 空间中,G1 为每个分配线程分配了一段独立的 ThreadLocal 空间,这样可以有效避免并发过程中的同步问题,从而保证让对象分配更快的进行。
如果 TLAB 内的空间无法完成分配,那么就会尝试在 Eden 空间中进行分配,也就是尝试在某个 Region 内进行分配。
如果对象的大小超过了 Region 一半的大小,那么,就只能在 Humongous 空间中进行分配了。
4. G1 回收过程
与此前其他垃圾回收器一样,G1 回收器也分为对 Eden 区进行的 Young GC 以及对老年代进行 的 Mix GC。
4.1 G1 中的 RSet 与 Card Table
对于只针对新生代或老年代进行的 GC,很显然,不能只扫描对应的分区,因为可能会有老年代对象引用新生代对象或新生代对象引用老年代的对象的情况,这样的话,无论回收哪个分区,都必须要对整个堆内存进行扫描,这显然是过于耗时而不能接受的。
正如我们在介绍 CMS 流程时所介绍的,CMS 通过 RSet 和 Card Table 实现了对上述情况的标记,G1 也使用了类似策略。
RSet 就是 RememberedSet,他跟踪了跨越 heap 区的引用,与 CMS 相反,G1 没有记录当前分区引用了哪些分区,而是在 RSet 中记录了哪些分区引用了当前分区的对象,这是因为 G1 采用细分的 Region 造成分区过多,同时,一个对象可能会引用非常多个对象,如果记录当前分区引用的分区,扫描范围仍然会很大。
但是,光是记录哪些分区引用了当前分区,并且去扫描这些引用了当前分区的分区中的对象,扫描的开销仍然很大,因此 G1 引入了 Card Table,和 CMS 中一样,一个 Card Table 将一个 Region 划分为 128 到 512 字节之间为单位的若干个 Card,通过标记 Card 是否为脏及是否被引用,可以让上述扫描过程进一步精细化。
4.2 SATB
G1 的回收过程整体上分为标记过程与回收过程,由于标记过程是并发进行的,和 CMS 一样,会在标记过程中产生新的漏标对象,从而可能造成对象被错误地回收掉。
为了避免这种情况的发生,G1 引入了 SATB,他是 Snapshot-At-The-Beginning 的缩写。
SATB 机制维护了一个双向链表,指向每个新分配的对象,这样垃圾回收器可以轻松的知道在开始 GC 后新分配的对象,从而避免对象被误回收,但这样会造成回收过程中产生的新的垃圾对象没有被回收,造成 float garbage。
4.3 Young GC
基于上述的数据结构,Young GC 的主要工作流程是:
- 标记 -- 扫描静态和本地对象
- 处理 dirty card,更新 RSet
- 检测从年轻代指向老年代的对象
- 对象拷贝
- 处理软引用、弱引用与虚引用
事实上,回收的重点在于对象拷贝的过程,在这一过程中,G1 将 Eden 区的活跃对象拷贝到 survive 区,如果 survive 区满,则会直接晋升到 old 区,survive 区中经过多次没有回收的对象也会晋升到 old 区。
4.4 Mix GC
Mix GC 是用来对老年代进行回收的,他分为两步:
- 全局并发标记
- 拷贝存活对象
全局并发标记共分为五个阶段:
- 初始标记 -- 对 GC Roots 进行标记,需要 Stop The World
- 根区域扫描 -- 在初始标记的存活 Region 中扫描对老年代的引用,并标记被引用对象
- 并发标记 -- 在整个堆中标记存活对象,可中断
- 最终标记 -- 清空 SATB 缓冲区,跟踪未被访问的存活对象,该阶段需要 Stop The World
- 清除垃圾 -- 也就是并发清除阶段,在执行 GC 统计和净化 RSet 过程中需要 Stop The World
4.5 Full GC
由于划分 Region,让 G1 更不容易产生内存碎片,但无论如何,内存碎片还是会随着 jvm 的工作而不断产生。
在 Mix GC 之前,老年代已经被填满,或者 Young GC 过程中向老年代晋升的内存分配失败,或者分配巨型对象失败,都会触发串行化的 Full GC
5. G1 的优势和不足
G1 最大的优势在于将堆内存空间离散化,从而提升对象分配和回收的效率,减少内存碎片的产生。
与此同时,G1 垃圾回收器还拥有停顿预测模型,从而能够尽量满足用户所设定的 GC 预期停顿时间,从而让整个回收过程更加可控。
但是,G1 的停顿预测功能并不能将回收过程精准的保证在所设定的时间范围内。
6. G1 的相关参数
上面介绍了 G1 使用的基本参数,可以看到 G1 垃圾收集器并不需要用户配置繁琐的参数就可以较好的工作,但我们仍然可以通过有限的参数来进行性能调优。
G1 拥有以下参数:
参数 | 含义 |
|---|---|
-XX:G1HeapRegionSize=n | 设置Region大小,并非最终值,因为最终只能取 2 的幂大小 |
-XX:MaxGCPauseMillis | 设置G1收集过程目标时间,默认值200ms,不是硬性条件 |
-XX:G1NewSizePercent | 新生代最小值,默认值5% |
-XX:G1MaxNewSizePercent | 新生代最大值,默认值60% |
-XX:ParallelGCThreads | STW期间,并行GC线程数 |
-XX:ConcGCThreads=n | 并发标记阶段,并行执行的线程数 |
-XX:InitiatingHeapOccupancyPercent | 设置触发标记周期的 Java 堆占用率阈值。默认值是45%。这里的java堆占比指的是non_young_capacity_bytes,包括old+humongous |
如果大对象比较多,可以将 Region 适当设置大一些,从而防止频繁分配巨型对象。
ParallelGCThreads 参数通常不建议设置 8 以上,除非处理器不止 8 个,建议设置为处理器的 5/8 左右,ConcGCThreads 则建议设置为 ParallelGCThreads 的 1/4,防止过多占用工作线程的资源。
附录 - 参考资料
https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html
http://dl.acm.org/citation.cfm?id=1029879
https://hllvm-group.iteye.com/group/topic/44381
https://hllvm-group.iteye.com/group/topic/44529
https://tech.meituan.com/2016/09/23/g1.html
http://ghoulich.xninja.org/2018/01/27/understanding-g1-garbage-collector-in-java/
边栏推荐
- 别焦虑了,这才是中国各行业的工资真相
- 手把手教你在Windows 10安装Oracle 19c(详细图文附踩坑指南)
- Current market situation and development prospect forecast of global concrete shrinkage reducing agent industry in 2022
- 数据同步工具 DataX 已经正式支持读写 TDengine
- xctf攻防世界 MISC薪手进阶区
- 利用OpenCV执行相机校准
- Exporting coordinates of points in TXT format in ArcGIS
- Solution to Maxwell error (MySQL 8.x connection)
- 国际数字经济学院、华南理工 | Unified BERT for Few-shot Natural Language Understanding(用于小样本自然语言理解的统一BERT)
- The computer voice is blurry, the video is also out of the card, and the sound cannot be played. It is normal to insert the headset
猜你喜欢

Mise à jour SQL mise à jour par lots

The first in China! EMQ joined Amazon cloud technology's "startup acceleration - global partner network program"

金源高端IPO被终止:曾拟募资7.5亿 儒杉资产与溧阳产投是股东

Row to column and column to row in MySQL

Hikvision Tools Manager海康威视工具大全(含SADP、录像容量计算等工具)百万安防从业者的实用工具

SQL update批量更新

Wechat applet payment countdown

Don't worry. This is the truth about wages in all industries in China

MySQL数据库登录和退出的两种方式

昱琛航空IPO被终止:曾拟募资5亿 郭峥为大股东
随机推荐
Win10 LTSC 2021 wsappx CPU 占用高
在arcgis中以txt格式导出点的坐标
Keras deep learning practice (12) -- facial feature point detection
The difficulty of realizing time series database "far surpassing" general database in specific scenarios
9.OpenFeign服务接口调用
为什么要从 OpenTSDB 迁移到 TDengine
如何封裝調用一個庫
清华徐勇、段文晖研究组开发出高效精确的第一性原理电子结构深度学习方法与程序
[webinar] mongodb and Google cloud accelerate enterprise digital innovation
Characteristics of time series data
Hi,你有一份Code Review攻略待查收!
Row to column and column to row in MySQL
VS code 运行yarn run dev 报yarn : 无法加载文件XXX的问题
Keras深度学习实战(12)——面部特征点检测
Usage of rxjs mergemap
Contest3182 - the 39th individual training match for 2021 freshmen_ F: ss
PostgreSQL数据库WAL——资源管理器RMGR
Don't worry. This is the truth about wages in all industries in China
原创 | 2025实现“5个1”奋斗目标!解放动力全系自主非道路国四产品正式发布
Summary of domestic database certification test guide (updated on June 16, 2022)