JVM学习日记⭐️G1收集器的原理和设计思想(上)⭐️

189 阅读4分钟

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

🔉引言

其实G1收集器也是属于经典垃圾收集器的,但是我并没有放到一起,原因是G1的内容太多,怕读者会产生疲倦,所以就单独列出一篇,包括后面的低延时垃圾收集器,也会根据实际情况进行分篇处理,关于垃圾收集器的介绍已经写过三篇文章,感兴趣的小伙伴可以去阅读我的专栏,就不多提了,这里。

Garbage First收集器

Garbage First收集器也叫G1收集器,它是垃圾收集技术的一个里程碑,开创了一个面向局部收集的设计思路和基于Reigon的布局方式,先吹嘘一波,后续我们一起看看。

G1主要是面对服务端的垃圾收集器,官方希望它能取代JDK5CMS垃圾收集器,那这个期望在JDK9就已经落地实现过半了,G1将取代Parallel Scavenge收集器⭐️和Parallel old收集器⭐️的组合,成为服务端默认的垃圾收集器,而CMS也成为不推荐使用的收集器。

由于历史弥留原因,CMS的代码与HotSpot的内存管理、执行、编译、监控等子系统都有联系,设计上并不符合职责分离原则,因此JDK10就提出了统一垃圾收集接口,将实现和行为划分开来,这样剔除或加入某款垃圾收集器也是风险可控,为G1取代CMS的历史舞台提供安全保障。

📆停顿时间模型

作为CMS的后继者,设计者们当然对它寄予了非常大的期望,希望做出一款能建立停顿时间模型的垃圾收集器,这是啥意思呢,就是说啊,你在一个M毫秒的片段内,消耗在垃圾收集上的时间要不超过给定的N毫秒。

📉面向局部

那怎么实现呢?首先要从思想上开始改变,在G1的垃圾收集器出现之前,我们设计的垃圾收集器要么是针对整个新生代(Minor GC),要么是针对整个老年代(Major GC),要么是针对整个堆(Full GC)。那我们就可以在思路上做调整,我不要它针对具体的哪块内存了,我需要它面向堆内的任何部分,进行组合式的垃圾搜集,于是就有了混合GC的思想(Mixed GC)。

📈基于Reigon

那*基于Reigon**的布局方式是实现这个垃圾收集器的关键,G1是怎么做的呢?我不在针对固定大小及固定数量的内存区域划分了,而是把java堆都分成一个个独立的Reigon,每个Reigon的大小相等,并且其根据需要进行Eden、Survivor、老年代空间的扮演,然后收集器可以根据不同的角色进行不同的处理,这样就能取到很好的收集效果。

Reigon中还有专门存储大对象的地方,称为Humongous,只要是对象的大小超过Reigon的一半,即可定义为大对象,每个Region的大小当然也是可以用参数设定的。通过:-XX:G1HeapRegionSize,取值范围1-32MB。那我要是来特大的对象,甚至都超过整个Reigon怎么办呢?这时就可以把这样的对象放到N个连续的HumongousReigon中,如图。

image.png

G1的设计思想看起来好像没有什么太多的创新,但实际的设计细节可远远没有你想象的那样简单,G1收集器至少有以下的问题需要解决:

  • 跨代引用
  • 并发标记
  • 停顿预测

内容太多,主要是肝不动了,分篇了。。。。。

📝题外话

爱因斯坦谈宗教与科学:人类所做的和所想的一切都与满足情感需求抑制痛苦有关。如果人们试图理解精神活动及其发展,就必须牢记这一点。情感渴望是人类一切努力和创造的动力,尽管后者可能会以非常崇高的形式呈现。那么,是怎样的情感和需求引领人们的宗教思想以及广义上的信仰呢?

这是个不错的问题,你们知道答案嘛?评论区留言吧。