JVM学习日记⭐️ZGC的原理及设计思想(下)

98 阅读7分钟

“这是我参与8月更文挑战的第29天,活动详情查看:8月更文挑战

🔉引言

接下来,我们了解一下ZGC是如何工作的,ZGC的运作过程大小分为4个阶段,这4个阶段都是并行执行的,仅有两个小的阶段之间会存在暂停阶段,比如我们熟悉的G1Shenanadoah,都有一个初始化标记的阶段,那ZGC也是一样,这里就不浪费笔墨多介绍了。如下所示: image.png

ZGC运作过程

并发标记(Concurrent Mark):该阶段是进行遍历图做可达性分析的阶段,同G1Shenanadoah一样,也要经过G1Shenanadoah的初始标记和最终标记的暂短停顿,不同的是:ZGC的标记是在指针上进行的,而不是在对象上进行,标记阶段会更新染色指针的Marked0Marked1标志位。

并发预备重分配(Courrent prepare for Relocate):这个阶段需要计算出哪些是需要清理的Region,然后将这些Region组成重新分配集Relocation Set),与我们提到的G1的回收集不同,哪块不同呢?目的不同,ZGC并不是划分G1的目的并不是做收益优先的增量回收,相反,ZGC每次回收都会扫描所有的Region,以便用范围更大的扫描成本来换取G1中记忆集的维护成本,因此,ZGC并不是说回收行为是针对某个Region进行的,而是针对全堆(有没有想起一句话:我不是说你啊,我是说在场的所有人,哈哈),所以只要绝对了重新分配集的存活对象被重新分配到了新的Region,就可以把该Region回收释放。需要注意的是:JDK12中ZGC开始支持类卸载和弱引用的处理就是该阶段进行的。

并发重分配(Courrent Relocate):并发预备重分配显然是给并发重新分配做准备的,该阶段也是ZGC执行过程的核心阶段,是把重新分配集中的存活对象复制到新的Region中,并为每个重新分配的Region维护一个转发表(Forward Table),这个表是干什么用的呢?是用来记录旧对象到新对象的转向关系的,这还要得益于染色指针的支持,ZGC收集器就可以从引用上获取对象是否处于重新分配集中,如果此时有用户线程并发访问了重分配集中的对象也没关系,该访问首先会被预置的内存屏障所截获,之后呢,看看Region上的转发表,然后把访问转发到新复制的对象上,同时更新该引用的值,事它直接指向新对象,这个过程就好比:你们吵架了,你的女朋友搬家了,去哪了,不告诉你,然后你通过搬家记录找到了你女朋友新的住址,就更新你大脑里面的住址,然后火速飞奔过去,向她道歉,劝她和好。

ZGC将这种行为称为指针的自愈能力,相对而言,有了转发表以后呢,只需要一次旧对象的陷入转发操作就行了,而Shenandoah是每次都进行转发操作,因此ZGC的运行用户负载更低一些,另一个好处是重分配集中一旦有一个Region内的存活对象被复制完毕后,该Region可以立即回收释放,用于分配新的对象。

并发重映射(Concurrent Reap):前面提到了指针自愈,接下来说重映射,重映射是更新对象引用关系的,那既然可自愈,为何还需要重映射呢?最多只是第一次使用时,多一次转发和修正操作而已嘛,当然目的是把这都省了,嘿嘿,由于有自愈所以不是很迫切,ZGC还更加精妙的把这一阶段的操作都挪到并发标记阶段完成,反正都是要遍历所有对象的,这就省去遍历一次对象图的开销,直到所有指针都更新后,原来记录新对象引用关系的转发表才可以释放。

总结

ZGC的设计与Shenandoah一样,都是全程支持可并发,短暂停顿也只与GCRoots的大小有关,同样实现了任何堆上停顿都小于10Ms的目标。

同一些先进的垃圾收集器相比,ZGC没有使用记忆集,因此避免了占用大量的空间,没有使用写屏障,减少了程序运行的额外负担,但是这种选择同样限制了它对象的分配速率不能太高,因为ZGC是面向全堆做垃圾收集的,如果对象的分配速率很高,就会创造大量的新对象,那这些新对象又很难进入当前的垃圾收集行为的标记范围,那就都当存活对象来看待呗,这就产生了大量的浮动垃圾,那会大大加长每一次进行并发收集的完整时长,由于大量的浮动垃圾存在,导致堆中可挪动的空间就更小了,因此必须加大内存空间,以此获得喘息机会。

要想进行对象分配速率的提升,还得引入分代收集,针对专门给新对象分配的这块区域进行更快更频繁的收集才行。

📝题外话

以下内容节选自《爱因斯坦晚年文集》,原文可能是晦涩难懂,这里尽量用白话文重新陈述。

爱因斯坦谈信仰,科学与宗教:在20世纪,以及19世纪、18世纪,人们广泛认为信仰和知识之间有不可调和的矛盾,什么矛盾呢?就是人们认为信仰必须要建立在基础知识之上,比如人们的通识或者道德规律什么的,你要是不建立这个知识之上,多半就是迷信。迷信我们是反对的。

信仰最好要得到经验和清晰思维的支持,但是这种说法是片面的,因为有一些对于我们的行为有必要而且起决定作用的信念不能用此种僵化的科学方法寻找。

科学方法是什么呢?科学方法能教给我们的只是,事实是如何相互联系,又是如何相互制约的。就是你可以说信仰和知识之间有联系,但并不是所有的信仰都受知识制约的,就像是什么并不等于怎么样是一样的道理。

人们可以对是什么有最清楚完整的认识,但是要想从中推论出我们人类渴望的目标是什么是做不到的。

接着提到了客观知识,客观知识只是我们实现某些目标的一个强有力的工具,但是实现终极目标和终极目标本身的源泉来自于另一个地方。

接着扩展到真理的知识,这类知识本身是伟大的,但是作为指导行动的能力实在太弱,因此,我们在此面临着关于我们的存在的纯粹理性观念的局限。

我们可以意识到某种手段能实现某种目的时,该手段也就是目的,仅此我们只是明白了手段和目的之间的关系,但并不能弄清楚终极和根本目的的层面,换句话来说,(PS:我觉得爱因斯坦追求的并不是真理本身,而是真理背后复杂的科学精神,这是他持久进行科研的动力,这种精神不是理智能思考明白的,存在于理智之外)。

那既然终极目标存在于理智之外,那是怎么存在和权威的呢?它们的成立当然不是通过证明,而是通过启示,通过有强有影响力的作用而得到,人们不应该试图证明其正当性,而应该单纯而明确地感受其本质。