深入理解G1垃圾收集器,同时解决关于GC垃圾收集器学习过程中容易混淆的概念和误区(请逐字阅读)

本文对垃圾回收和G1中容易误解的概念和难以理解的概念作阐述,解决新手学习GC的障碍。

一:关于垃圾回收器中容易误解的概念:

1.并行和并发

       [1]:在线程的语境下(上下文中):

                并行:同一时间点,有多个任务被执行。

                并发:同一时间段,有多个任务被执行,同一时间点上,只有一个任务在执行。

       [2]:在垃圾回收的语境下(上下文中):

              并行:在用户线程处于等待状态(STW)时,有多个垃圾回收线程并行(线程语境下)工作。

                串行:在用户线程处于等待状态(STW)时,只有一个垃圾回收线程工作

                并发:用户线程与垃圾回收线程并行(线程语境下)工作

注:所有的垃圾回收器都有STW(Stop The World),所以即便是并发的垃圾回收器,也一定会有STW。

记忆集(Remember Set):每个Region(G1的分区)都有一个记忆集,每次对引用类型变量赋值时,都会产生一个Write Barrier(写屏障),判断引用指向的对象是否和该引用在同一个Region,如果不同,在CardTable中把相关引用信息记录到该引用所指向的对象所在Region的记忆集中。如果卡表中的信息发生更改,比如重新给引用赋值,此时card被标记为脏,进入脏卡表队列,等待YGC时进行操作。

G1的分区(Region):有Eden,Survivor,Old,Humongous(超大对象)区,还有很多空区(毕竟是复制算法),所有的区在清空后,区的属性可以重新改变(当然也可以不变)。比如原来是S区,清空后可以作为O区用。空闲的区域也可以作为任意一种区使用。

Humongous(超大对象)区:大家思考一下,为什么G1要设计一个超大对象区而不是直接把对象丢到老年代?

 超大对象比较容易因为Survivor区空间不足而直接晋升至老年代,但是老年代GC的频率极低(相较于YGC),那么如果大对象不再被引用(变成垃圾),并长时间存放在老年代,某种程度上也算是"内存泄漏",所以设计了超大对象区便于回收.

 

二:垃圾回收过程:

 

  G1垃圾回收器的过程:YGC->YGC+并发标记->混合回收。

 

1.G1的年轻代回收器是一个并行(垃圾回收语境下)的独占式(STW)垃圾回收器,当堆内存使用空间达到一定值(默认为45%)时,才触发并发标记过程,这个阈值可以自己设置。

2.首先G1创建回收集,回收集指的是需要被回收的内存分段的集合,通常包含整个Survivor区和Eden区。

3.开始YGC:

        (1):扫描GC Roots(比如static变量)和记忆集中的引用,作为扫描的根节点。

        (2):更新Rset(记忆集),通过脏卡表队列(dirty card queue)中的信息更新记忆集。

                大家不妨思考下,为什么要有一个脏卡表队列?

                因为如果用同步线程在每次赋值操作时更新记忆集,开销会很大,用队列在STW时更新,不会占用用户线程,开销会小很多。

        (3):处理Rset:识别被老年代指向的Eden区中的对象,将对象标记为存活

        (4):复制对象:Eden区和from区(Survivor的from区的简称),的对象被复制到to区,对象年龄+1,达到年龄阈值的对象会晋升到老年代。如果对象过大,survivor区放不下,则直接晋升到老年代。

        (5): 处理引用(上面四步回收的是强引用对象),接下来回收weak,soft,phantom,final引用对象,这类对象占比极少(1%左右),通常也就框架底层源码中能看到。

--------------------------------------------------------------------------------------------------

                并发标记阶段(堆内存占用达到阈值):

            [1]:标记从根节点(和上面一样,包括记忆集扫描)直接可达的对象,扫描过程中STW,同时触发YGC        

               [2]:根区域扫描:扫描从survivor区直接可达的老年代对象,并标记。这个过程必须在[1]的YGC之前,因为YGC会移动Survivor区的Region。

                [3]:并发标记(垃圾回收语境下的并发):可以与应用程序并行(线程语境下)执行,标记空间内完全(100%)是垃圾的Region。 计算每个Region中存活对象的比例。

                [4]再次标记:停止应用程序并修正上一次的标记结果。

                [5] 独占清理: STW,识别各个Region的存活对象并统计GC回收的收益,进行优先级排列,同时识别可以混合回收的区域。注意,这个阶段没有回收任何垃圾。

                [6]并发清理:清理在[3]中被标记为完全是垃圾的Region。

------------------------------------------------------------------------------------------------------------------

                混合回收阶段:

                简单来讲就是每次进行Mixed GC时对Eden区,Survivor区和部分Old区进行GC。

                混合回收的回收集包括Eden,Survivor和八分之一的Old区。            

               混合回收的算法和YGC一样,只不过多了一部分老年代区域。

                两点注意事项:

                1.垃圾比例低于一定阈值的Region不会被回收。

                2.回收集内的垃圾低于堆内存的10%,不会进行此次回收。

            

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值