G1垃圾回收器

垃圾回收过程

G1运行过程
在这里插入图片描述
G1的运行过程大致分为四个步骤:

1.初始标记-暂停用户线程

这个阶段是STW(Stop the World )的,所有应用线程会被暂停,标记出从GC Root开始直接可达的对象。

2.并发标记-用户线程并发

从GC Roots开始对堆中对象进行可达性分析,找出存活对象,耗时较长。当并发标记完成后,开始最终标记(Final Marking )阶段

3. 重新标记-暂停用户线程

标记那些在并发标记阶段发生变化的对象,将被回收。

4.清理 - 暂停用户线程

首先对各个Regin的回收价值和成本进行排序,根据用户所期待的GC停顿时间指定回收计划,回收一部分Region。
最后,G1中提供了两种模式垃圾回收模式,Young GC和Mixed GC,两种都是Stop The World(STW)的。

G1回收垃圾过程图
在这里插入图片描述
顺时针,yong gc -> yong gc + concurrent mark -> Mixed GC顺序,进行垃圾回收。

1. 年轻代GC(Yong GC)

在分配一般对象(非巨型对象)时,当所有eden region使用达到最大阀值并且无法申请足够内存时,会触发一次YoungGC。每次younggc会回收所有Eden以及Survivor区,并且将存活对象复制到Old区以及另一部分的Survivor区。

YoungGC的回收过程如下:

第一阶段,扫描根。
根引用连同Rset记录的外部引用作为扫描存活对象的入口。

第二阶段,更新RSet.
处理dirty card queue(见备注)中的card,更新RSet。此阶段完成后,RSet可以准确的反映老年代对所在的内存分段中对象的引用。

第三阶段,处理RSet。
识别被老年代对象指向的Eden中的对象,这些被指向的Eden中的对象被认为是存活的对象。

第四阶段,此阶段,对象树被遍历,Eden区内存段中存活的对象会被复制到survivor区中空的内存分段,Survivor区内存段中存活的对象如果年龄未达阈值,年龄会加1,达到阀值会被会被复制到old区中空的内存分段。如果survivor空间不够,Eden空间的部分数据会直接晋升到老年代空间。

第五阶段,处理引用。
处理引用队列,软引用,弱引用,虚引用。最终Eden空间的数据为空,Gc停止工作,而目标内存中的对象都是连续存储的,没有碎片,所以复制过程可以达到内存整理的效果,减少碎片。

2.老年代并发标记过程(Concurrent Marking)

1.初始标记阶段:标记从根节点直接可达的对象。这个阶段是STW的,并且会触发一次年轻代GC。

2.根区域扫描(Root Region Scanning) : G1 GC扫描survivor区直接可达的老年代区域对象,并标记被引用的对象。这一过程必须在young GC之前完成。

3.并发标记(Concurrent Marking):在整个堆中进行并发标记(和应用程序并发执行),此过程可能被young GC中断。在并发标记阶段,若发现区域对象中的所有对象都是垃圾,那这个区域会被立即回收。同时,并发标记过程中,会计算每个区域的对象活性(区域中存活对象的比例)。

4。再次标记(Remark):由于应用程序持续进行,需要修正上一次的标记结果。是STW的。G1中采用了比CAS更快的初始快照算法:snapshot-at-the-beginning (SATB)。

5.独占清理(cleanup,STW):计算各个区域的存活对象和cC回收比例,并进行排序,识别可以混合回收的区域。为下阶段做铺垫。是STW的,这个阶段并不会实际上去做垃圾的收集。

6.并发清理阶段:识别并清理完全空闲的区域。

SATB(Snapshot At The Beginning)维护被删除的旧引用

SATB正如他的名字一样,在开始并发标记前会对所有对象做一个快照,抽象的说就是在一次GC开始的时候是活的对象就被认为是活的。这样可以防止标记过程中有对象被删除引用后再被其他新对象添加引用导致的误标。如何实现这种快照也很简单,仍然需要使用到上文介绍到的 写屏障 技术, 在有对象的引用被删除时将该引用给记录下来 即可。这样的话在重新标记的阶段只需要扫描这些内容就可以快速恢复快照的内容。当然这种快照的方式肯定会使得一些本应该被标记回收的对象没有被回收成为浮动垃圾,但是并不影响GC的正确性,等待下次GC清除即可。

3.混合回收(Mixed GC)

当越来越多的对象晋升到老年代old region时,为了避免堆内存被耗尽,虚拟机会触发一个混合的垃圾收集器,即mixed gc,该算法并不是一个old gc,除了回收整个young region,还会回收一部分的old region,这里需要注意:是一部分老年代,而不是全部老年代,可以选择哪些old region进行收集,从而可以对垃圾回收的耗时时间进行控制。

G1没有fullGC概念,需要fullGC时,调用serialOldGC进行全堆扫描(包括eden、survivor、old、perm)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
G1(Garbage First)垃圾回收是一种低延迟的垃圾回收,它可以在不影响应用程序吞吐量的情况下,有效地处理大量的内存垃圾。下面是G1垃圾回收的执行流程: 1. 初始标记(Initial Mark):该阶段的目标是标记所有的根对象,并且标记从根对象直接可达的对象。为了达到这个目的,G1垃圾回收会扫描所有的Java线程的栈,以及记录下所有的GC Root。 2. 并发标记(Concurrent Mark):在初始标记之后,G1垃圾回收会开始并发标记所有从根对象可达的对象。这是一个并发的过程,不会阻塞应用程序的执行。 3. 最终标记(Final Mark):在并发标记之后,G1垃圾回收会再次暂停应用程序的执行,以完成所有未被标记的存活对象的标记。这个过程与初始标记是类似的。 4. 筛选回收(Live Data Counting and Evacuation):在最终标记之后,G1垃圾回收会计算每个区域中存活的数据量。然后,它会选定一些区域作为回收集(Collection Set),将这些区域中的存活对象复制到空闲的区域中,并将这些区域标记为可回收的。 5. 清除(Cleanup):在筛选回收之后,G1垃圾回收会开始清理所有被标记为可回收的区域。 需要注意的是,G1垃圾回收是一个全局垃圾回收,因此它不仅仅会处理单个堆区域的垃圾回收,而是会处理整个Java堆。同时,它还会根据应用程序运行的情况,动态地调整回收集的大小,以达到最佳的垃圾回收效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值