美文网首页JavaJava 核心技术编程语言爱好者
G1能作为JDK9默认垃圾回收器的优势分析

G1能作为JDK9默认垃圾回收器的优势分析

作者: 迦叶_金色的人生_荣耀而又辉煌 | 来源:发表于2020-12-15 07:11 被阅读0次

CMS收集器存在哪些缺点

1、只适用于老年代,采用标记清除算法,实现GC和用户线程同时执行,减少STW时间
2、标记清除算法会产生大量碎片化问题
3、存放大对象会直接晋升到老年代,如果不频繁使用,会非常浪费堆内存空间
4、大对象很容易造成fullgc,所有工作线程会触发STW问题,导致工作线程阻塞。

什么是G1收集器

1.G1是一个并行/并发回收器,它把堆内存分割为很多不相关的区域(Region) (物理上不连续的)。
使用不同的Region来表示Eden、幸存者0(S0)区,幸存者(S1)1区,老年代等。
2.侧重点在于回收垃圾最大量的区间(Region),所以我们给G1一个名字:垃圾优先(Garbage First) 。
3.G1 GC有计划地避免在整个Java 堆中进行全区域的垃圾收集。
G1跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。

G1垃圾回收器的目标:可配置在N毫秒内最多只占用M毫秒的时间进行垃圾回收,全部复制算法。

垃圾回收核心原理

1.使用Rset找关联关系【跨带引用关联】

在一个region中可能会引入到其他的region,为了避免不需要的全局扫描,在每个region中都对应一个Remembered Set(记忆集),使用CarTable
记录每个region区相互引用的关系。

2.使用cset表里可回收的空间(可能20%、50%和100%等),把尽可能回收完的空间进行回收。

Collection Set(CSet)记录了GC要收集的Region集合,集合里的Region可以是任意年代的

候选老年代分区的CSet准入条件,可以通过活跃度阈值-XX:G1MixedGCLiveThresholdPercent(默认85%)进行设置,从而拦截那些回收开销巨大的对象;
每次混合收集可以包含候选老年代分区,可根据CSet对堆的总大小占比-XX:G1OldCSetRegionThresholdPercent(默认10%)设置数量上限。
由上述可知,G1的收集都是根据CSet进行操作的,年轻代收集与混合收集没有明显的不同

3.使用写屏障确保新生代对象被老年代对象引用的时候不被gc

写屏障,其实就是指在赋值操作前后,加入一些处理(可以参考AOP的概念):记录赋值的操作。
老年代存活对象多时,每次minor gc查询老年代所有对象影响gc效率(因为gc stop-the-world),所以在老年代有一个write barrier(写屏障)来管理的card table(卡表),card table存放了所有老年代对象对新生代对象的引用。
所以每次minor gc通过查询card table来避免查询整个老年代,以此来提高gc性能

Heap信息:
 garbage-first heap   total 570368K, used 307771K [0x00000006c0000000, 0x00000006c0101168, 0x00000007c0000000)
  region size 1024K, 2 young (2048K), 1 survivors (1024K)
 Metaspace       used 3129K, capacity 4568K, committed 4864K, reserved 1056768K
  class space    used 337K, capacity 392K, committed 512K, reserved 1048576K

G1收集器特色

1.并行与并发

并行:在主线程暂停的情况下,使用并行收集
G1收集器在回收时,可以实现多个GC线程同时执行 利用CPU多核利用率,但是会让用户线程暂停 触发stw机制。
并发:在主线程运行的情况下,使用并发收集
多个GC与用户线程用时执行,用户线程不会阻塞。

2.分代收集原理

G1收集器,也会分为新生代eden、S0或者S1区域,但是不要求整个eden、S0或者S1区域具有连续性。


一个region(分区)只能属于一个角色,有可能为eden区、S区、老年代等, E表示为Eden区、S区表示为S1,S0区,老年代O区 空白的表示为未使用的分配的内存。H区存放巨型对象

巨型对象设计原理:
a、一个对象大于region的一半时,称之为巨型对象,会专门弄一个H区存放巨型对象
b、如果一个H区装不下的情况下,则会寻找连续H区存储
c、如果还没有足够的空间,有可能会引发FULLGC.
d、回收时会优先回收

2.0垃圾回收顺序:
young gc(新生代) 一> young gc + concurrent mark(新生代+并发标) 一> Mixed GC(混合回收)顺序,进行垃圾回收

2.1YoungGC(新生代)回收

使用标记复制算法,将还有引用的对象清理到新的S区,然后清空原有所有的E和S区。

2.2young gc + concurrent mark(新生代+并发标)回收
  1. 初始标记:标记GCroot对象,还会标记我们的region(块)
  2. 标记Region:根据我们rset 找到对应和rootRegion相关的region块进行标识
  3. 并发标记:遍历所有的rootRegion引用的所有的区标记我们所有的可达对象(不会STW,jvm配置参数-XX:InitiatingHeapOccupancyPercen=45%)
  4. 重新标记:同CMS一样,只不过G1中采用了比CMS更快的初始快照算法:snapshot一at一the一beginning (SATB)。
  5. 清理:清理采用的是复制算法。这里清理只会选取垃圾较多的region
2.3MixGC(混合)回收(图形参考CMS)

回收整个Young Region(新生代区域),部分的老年代区域,如果G1无法有足够的空间复制对象的时候,有可能会引发FullGc

3.空间整合

之前我们所学习的CMS收集器采用标记清除算法,容易产生碎片化的问题且空间不连续性,而G1收集器划分成n多个不同的采用标记压缩算法,没有产生碎片化的问题。分配大对象的时候,避免FullGC的问题,所以如果堆内存空间比较大,使用G1收集器更加有优势。

4.可预测的停顿时间模型

能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
由于G1收集器采用分区模型,所以G1可以只选取部分区域进行内存回收,这样缩小了回收的范围,因此对于全局停顿情况的发生也能得到较好的控制。G1跟踪各个Region 里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。

5.局限性

最多支持2048块,每块大小在1-32M,内存需要配置在2G-64G。
内存配置至少在2G以上,小内存的话发挥不了功效,还不如使用CMS回收器。

参数设置

选项和默认值 描述
-XX:+UseG1GC 使用垃圾优先(G1)收集器
-XX:MaxGCPauseMillis = n 设置期望达到的最大Gc停顿时间指标 ,默认值是200ms
-XX:InitiatingHeapOccupancyPercent = n 启动并发GC周期的(整个)堆占用百分比。GC使用它来触发GC,该GC基于整个堆的占用来触发并发GC周期,而不仅仅是世代之一(例如,G1)。值为0表示“进行恒定的GC循环”。默认值为45。
-XX:NewRatio = n 新旧大小比例。预设值为2。
-XX:SurvivorRatio = n 伊甸园/幸存者空间大小之比。预设值为8。
-XX:MaxTenuringThreshold = n 任职期限的最大值。预设值为15。
-XX:ParallelGCThreads = n 设置垃圾回收线程数 最大设置为8
-XX:ConcGCThreads = n 设置并发标记的线程数。将n设置为并行垃圾回收线程数(ParallelGCThreads)的1/4左右。
-XX:G1ReservePercent = n 设置保留为虚假上限的堆数量,以减少升级失败的可能性。预设值为10。
-XX:G1HeapRegionSize = n 使用G1,Java堆可细分为大小一致的区域。这将设置各个细分的大小。该参数的默认值是根据堆大小按人机工程学确定的。最小值为1Mb,最大值为32Mb。

相关文章

  • G1能作为JDK9默认垃圾回收器的优势分析

    CMS收集器存在哪些缺点 1、只适用于老年代,采用标记清除算法,实现GC和用户线程同时执行,减少STW时间2、标记...

  • G1的原理了解吗?

    G1作为JDK9之后的服务端默认收集器,且不再区分年轻代和⽼年代进⾏垃圾回收,他把内存划分为多个Region,每个...

  • 面试官:谈谈你对G1垃圾收集器有哪些了解?

    作为一款高效的垃圾收集器,G1在JDK7中加入JVM,在JDK9中取代CMS成为了默认的垃圾收集器。 1、垃圾收集...

  • G1垃圾回收器在并发场景调优

    一、序言 目前企业级主流使用的Java版本是8,垃圾回收器支持手动修改为G1,G1垃圾回收器是Java 11的默认...

  • 对G1垃圾收集器的了解

    作为一款高效的垃圾收集器,G1在JDK7中加入JVM,在JDK9中取代CMS成为了默认的垃圾收集器。 1.1 新生...

  • 垃圾回收算法

    G1垃圾回收和其他的区别 串行回收:主要面向单线程环境 并行/吞吐量回收器:JVM默认回收器,Parallel c...

  • G1垃圾回收器

    垃圾回收器的发展历程 背景 01、G1解决的问题 G1垃圾回收器是04年正式提出,12开始正式支持,在17年作为J...

  • Java 垃圾回收器之G1详解

    Java 垃圾回收器之G1详解 概述 G1垃圾回收器是在Java7 update 4之后引入的一个新的垃圾回收器。...

  • JVM Java G1 垃圾收集器

    本文简单介绍了垃圾收集的几种常见式,重点说明了G1回收的原理(毕竟JDK1.9 G1会是默认的GC回收器–-...

  • G1垃圾收集器

    G1垃圾收集器在JDK1.7中投入使用,并作为JDK1.9默认的垃圾收集器。 JVM配置开启G1参数: 一、G1与...

网友评论

    本文标题:G1能作为JDK9默认垃圾回收器的优势分析

    本文链接:https://www.haomeiwen.com/subject/vbvygktx.html