【JVM】JVM内存结构之——G1收集器

【JVM】JVM内存结构之——G1收集器目录 1 什么是 G12 G1 收集器发展历程 3 G1 收集器分区划分 3 1 为什么 G1 收集器需要设计巨型对象 3 2G1 收集器参数设置 3 3G1 收集器回收的细节 3 4G1 收集器 Rset 问题 记忆集 3 5G1 两种回收策略 4 G1 收集器优缺点 5 G1 收集器核心配置参数 1 什么是 G1G1 收集器 Garbage FirstGarbage 整堆收集 G1 收集器是一款在 server 端运行的垃圾收集器 专门针对于拥有多核处理器和大内存的机器 在 JDK7u4 版本发行时被正式


1. 什么是G1

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

2. G1收集器发展历程

3. G1收集器分区划分

3.1 为什么G1收集器需要设计巨型对象

  1. 在G1收集器中也有一个新的内存区域,称作为:Humongous (H)区(巨型对象),主要存放一些比较大的对象,一个对象大于region的一半时,称之为巨型对象,G1不会对巨型对象进行拷贝,回收时会考虑优先回收。
    2.在以前收集器中,如果是一个大对象是直接放入到老年代中,而触发老年代GC不是很频繁,万一该大对象不是非常频繁的使用,则会非常浪费我们堆内存,为了解决这个问题在G1收集器专门弄一个H区存放巨型对象,如果一个H区装不下的情况下,则会寻找连续H区存储,如果还没有足够的空间,有可能会引发FULLGC.

3.2 G1收集器参数设置

-XX:+UseG1GC -Xmx32g -XX:MaxGCPauseMillis=200

其中-XX:+UseG1GC为开启G1垃圾收集器,-Xmx32g 设计堆内存的最大内存为32G,-XX:MaxGCPauseMillis=200设置GC的最大暂停时间为200ms。如果我们需要调优,在内存大小一定的情况下,我们只需要修改最大暂停时间即可。

3.3 G1收集器回收的细节

G1收集器回收过程分为三个环节:

  1. 年轻代GC(Young GC )
  2. 新生代和并发标记过程( Concurrent Marking
  3. 混合回收(Mixed GC )—-
  4. Full GC
    young gc(新生代) 一> young gc + concurrent mark(新生代+并发标) 一> Mixed GC(混合回收)顺序,进行垃圾回收。

1.应用程序分配内存,当年轻代的Eden区用尽时开始年轻代回收过程; G1的年轻代收集阶段是一个并行的独占式收集器。在年轻代回收期,G1 GC暂停所有应用程序线程,启动多线程执行年轻代回收。然后从年轻代区间移动存活对象到Survivor区间或者老年区间,也有可能是两个区间都会涉及。

2.当堆内存使用达到一定值(默认45%)时,开始老年代并发标记过程。—CMS

  1. 标记完成马上开始混合回收过程。对于一个混合回收期, G1 GC从老年区间移动存活对象到空闲区间,这些空闲区间也就称为了老年代的一部分。和年轻代不同,老年代的G1回收器和其他GC不同,G1的老年代回收器不需要整个老年代被回收,一次只需要扫描/回收一小部分老年代的Region就可以了。同时,这个老年代Region是和年轻代一起被回收的。

3.4 G1收集器Rset问题(记忆集)

2.如果是老年代指向年轻代的引用,那这个引用在Minor GC阶段是不能被回收掉的,那如何解决这个问题呢?

3.最合理的实现方式自然是记录哪些Region中的老年代的对象有指向年轻代的引用。GC时扫描这些Region就行了。这就是RSet存在的意义。RSet本质上是一种哈希表,Key是Region的起始地址,Value是一个集合,里面存储的元素是卡表的索引号。

4.现代JVM,堆空间通常被划分为新生代和老年代。由于新生代的垃圾收集通常很频繁,如果老年代对象引用了新生代的对象,那么,需要跟踪从老年代到新生代的所有引用,从而避免每次YGC时扫描整个老年代,减少开销。

5.对于HotSpot JVM,使用了卡标记(Card Marking)技术来解决老年代到新生代的引用问题。具体是,使用卡表(Card Table)和写屏障(Write Barrier)来进行标记并加快对GC Roots的扫描。

3.5 G1两种回收策略

G1 Young GC(新生代GC)
Young GC主要是对Eden区进行GC,它在Eden空间耗尽时会被触发。在这种情况下,Eden空间的数据移动到Survivor空间中,如果Survivor空间不够,Eden空间的部分数据会直接晋升到年老代空间。Survivor区的数据移动到新的Survivor区中,也有部分数据晋升到老年代空间中。最终Eden空间的数据为空,GC停止工作,应用线程继续执行。

G1 Mix GC(混合回收)

4. G1收集器优缺点

  1. 并行与并发
    并行:G1收集器在回收时,可以实现多个GC线程同时执行 利用CPU多核利用率,但是会让用户线程暂停 触发stw机制。 堆6个GB JDK8环境开启G1 jdk9默认使用
    并发:多个GC与用户线程用时执行,用户线程不会阻塞。

  2. 分代收集原理
    G1收集器,也会分为新生代、老年代, 新生代eden、S0或者S1区域,但是不要求整个eden、S0或者S1区域具有连续性。
    与之前的收集器不同,它可以收集新生代也可以收集老年代。

  3. 空间整合
    之前我们所学习的CMS收集器采用标记清除算法,容易产生碎片化的问题且空间不连续性,而G1收集器划分成n多个不同的采用标记压缩算法,没有产生碎片化的问题。分配大对象的时候,避免FullGC的问题,所以如果堆内存空间比较大,使用G1收集器更加有优势。
  4. 可预测的停顿时间模型 能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。
    由于G1收集器采用分区模型,所以G1可以只选取部分区域进行内存回收,这样缩小了回收的范围,因此对于全局停顿情况的发生也能得到较好的控制。G1跟踪各个Region 里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。

缺点:小内存的情况下使用cms收集器,大内存的情况下可以使用G1收集器。G1收集器6GB以上

5. G1收集器核心配置参数

-XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+PrintGCDetails -verbose:gc

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227940.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午8:10
下一篇 2026年3月16日 下午8:10


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号