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

1,183 阅读6分钟

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

🔉引言

由于内容太多,因此分上和下,主要原因是作者肝不动,这点我毫不避讳,闲话少扯,开始正题😛吧。

🌲 Garbage First收集器

❤️设计细节

- 跨代引用

例如,你是把java堆划分成多个独立的Reigon了,那跨代引用是如何解决的?(PS:传送门🚪(【跨代引用】),你透过传送门瞄了一眼,可以用记忆集啊,没错,使用记忆集确实可以避免全堆扫描,但是实际的设计要远比我们想像的复杂的多,因为G1需要给每个Region都维护一个记忆集,记忆集会记下别的Region指向自己的指针,并标记这些指针分别在哪个卡页范围内,我们可以把这样的数据结构看成是哈希表,KeyRegion的起始地址,Value是一堆集合,存储了卡表的索引号(PS:传送门🚪【卡表】),这种设计不光可以可以知道我指向谁,还能知道谁指向我,实现起来更为复杂,同时G1划分的Region也比原来的垃圾收集器分代数量多的多,因此其比传统的垃圾收集器占用更多的内存,根据经验,G1至少需要java堆的10%-20%进行额外的内存工作。

- 并发标记

前面我们提到,线程改变引用关系时,必须要保证不能改变原来的对像图,不然会发生标记错误,(PS:传送门🚪【关于并发标记的问题解决】);那CMS是使用增量更新实现的,那我们的G1就采用另外一种方式,原始快照算法实现。此外,程序要继续运行就会为新对象分配内存,那垃圾回收势必会对用户线程产生影响,如果内存回收速度赶不上内存分配速度,那G1也会被迫的冻结用户线程的执行,导致Full GC而产生时间较长的垃圾回收。

- 停顿预测

那如何建立起可靠的停顿模型呢?用户通过-XX:MaxGCPauseMillis指令的只是垃圾收集之前的一个期望值,那G1是怎么实现停顿模型呢?这里就不得不提衰减均值的概念了,衰减均值与普通的平均值不同,普通的平均值体现的只是整体平均状态,而衰减均值体现的是最近的平均状态,这就意味着它比普通的平均值更容易受到新数据的影响。那G1中的Region统计状态越新,就越能决定其回收的价值,然后在通过这些信息进行预测,使用哪些Region组成的回收集会在不超过期望停顿时间的基础上获得更高的收益,那G1会统计哪些信息呢?(在G1的运行过程中会统计Region的耗时,记忆集的脏卡数量等各个可测量的花费的成本,然后进行分析得出置信度、平均值、标准误差等信息)。

❤️执行过程

接下来说一下G1的运行过程,大体分为这么4步:

  • 初始标记(initial Marking
  • 并发标记(Concurrent Marking
  • 最终标记(Final Marking
  • 筛选回收(Live Data Counting And Evacation

初始标记

初始标记主要标记可直接被GCRoots关联的对象,然后修改TAMS指针的值(PS:G1为每个Region都设置了TAMS指针),这个阶段耗时很短,需要停顿线程,是和Minor GC同步完成的,以便在下一阶段用户线程并发时,为后续正确地在可用的Region中分配对象打基础。

并发标记

GCRoots开始,对堆中对象进行可达性分析,找出垃圾对象,该阶段耗时长,可与用户线程并发执行,当对象图扫描完成后,还需要重新处理SATB在此期间记录的引用变动的对象。

最终标记

对用户线程做一个简单暂停,用于处理并发阶段结束后仍遗留下来的少量的SATB记录

筛选回收

负责对各个Region的统计数据进行更新,将回收成本和价值进行排序,以便制定回收计划,可以自由选择多个Region构成回收集,然后把旧Region中存活的对象复制到新Region中,然后把旧Region清除,该操作涉及对象的移动,因此必须暂停用户线程,由多条收集线程执行完成。

🌲总结

可以看出,除并发标记外,G1的绝大多数操作都是需要暂停用户线程的,也就是说G1并不是纯粹的追求低延迟,而是要在延迟可控的情况下获得较高的吞吐量。

毫无疑问,可以指定用户的期望时间是G1收集器很强大的功能(PS:写到这我的脑子都不转了😴),不过期望值也不是随便设置的,不能想多少就设多少,因为是需要冻结线程复制对象的,默认是200MS,如果你设置的太短就会导致每次选出来的回收集只占内存的一小部分,很可能会发生收集器跟不上分配器的情况,最终导致堆满,发生Full GC严重影响性能的情况,一般来说设置一两百毫秒是合理的。

至于G1为何是里程碑原因是这样的,从G1开始,先进的垃圾收集器的设计思路就变了,不再关注一次清理整个堆,而是关注内存分配速率,只要收集的速度能跟上分配的速度,那一切就能运作的很完美😪。

📝题外话

宗教形成的第二个来源是社会情绪。无论父亲和母亲,还是较大的人类共同体的领袖们都不免一死和犯错。人们对指引、关爱与帮助的渴望促成了社会的或道德的上帝概念的形成。这位执掌天意的上帝,担当保护、决断、奖赏和惩罚的职责。上帝按照人类所处的不同层次,来爱护和抚育部落的生命或人类的生命,甚或生命本身。他是人在遭遇不幸和愿望未能达成时的安慰者,是死者灵魂的保护者。这就是社会的或道德的上帝概念。

噢噢噢噢😮!原来上帝是这么来的,学fei了。