面试官问我G1回收器怎么知道你是什么时候的垃圾? (3)

简介: 面试官问我G1回收器怎么知道你是什么时候的垃圾? (3)

并发标记(Concurrent Marking)


先看前面引用的书中描述:


并发标记(Concurrent Marking):从 GC Roots 开始对堆的对象进行可达性分析,递归扫描整个堆里的对象图,找出存活的对象,这阶段耗时较长,但是可以与用户程序并发执行。当对象图扫描完成以后,还要重新处理 SATB 记录下的在并发时有引用变动的对象。


再看动图:


从 GC Roots 开始对堆的对象进行可达性分析,递归扫描整个堆里的对象图,找出存活的对象:


意思就是说在并发标记阶段, GC 线程工作在 prevTAMS 和 NextTAMS 之间,对堆里的对象进行可达性分析(回想一下“三色标记”),标记完成后, NextBitmap 就有对应有值了(里面放的是地址值),黑色对应的是存活对象,白色对应的垃圾对象。

这样就找出存活对象了。


但是书中并没有提及用户线程分配对象的情况。所以读者提出的问题,在书中也找不到明确的答案。


答案就是: NextTAMS 与 Top 之间的对象,就是本次并发标记阶段用户线程新分配的对象,它们是隐式存活的。


为什么这么说?你去品一品论文里面我框起来的这句话。


但是面试官想要的是这一句话的答案吗?不是的。


你听到这个问题后,你先微微一皱眉,做出沉思状,然后轻轻说说一句:这个问题问的很好,我先组织一下语言。(先舔他一波)


然后你按照阶段把图画出来,指着给他讲 TAMS 和 Bitmap 是怎么工作的。


另外,关于 NextTAMS 与 Top 为什么是重叠的,也得补充说明一下:并发标记的前一个阶段是初始标记。由于初始标记是 STW 的,所以从动图中我们可以看到:并发标记开始,即初始标记结束的时候, NextTAMS 与 Top 是重叠的。


随着并发标记过程的进行, NextBitmap 被填充上了值。而 NextTAMS 与 Top 之间的区域越来越大,这就是用户线程在并发标记阶段分配的新对象。


同时通过下面的图我们可以看到, GC 线程的工作区间和用户线程的工作区间是有重叠的(用工作区间这个概念去理解其中的一些细节不一定正确,但是可以这样抽象的认为,方便理解)。


而重叠的部分,就是可能产生“对象消失”的部分。对G1来说,就是原始快照(STAB)加写前屏障(Pre-Wirte Barrier)工作的部分。


所以这就是书里为什么说:当 GC 线程扫描完对象图后,还需要重新处理 STAB 记录下的在并发时有引用变动的对象。


最终标记(Remark)


书中是这样的写的:


最终标记(Final Marking):对用户线程做另一个短暂的暂停,用于处理并发阶段结束后仍遗留下来的最后那少量的 SATB 记录


最终标记阶段,由于是 STW 的,所以该阶段对应的图是并发标记阶段完成后的图,如下:


处理并发阶段结束后仍遗留下来的最后那少量的 SATB 记录是什么意思呢?

你想,并发标记阶段, GC 线程完成对象图的扫描之后,还会去处理 SATB 记录下的在并发时有引用变动的对象。


在处理 SATB 记录的数据的时候,由于用户线程可能还是在继续修改对象图,继续在产生 SATB 数据,所以还是会有一小部分的 SATB 数据,所以才需要一个短暂的暂停。


清理阶段(Cleanup)


书里写的是筛选回收阶段。其实就包含了清理阶段和回收阶段。这里我们只讨论清理阶段,不讨论回收。


在这个阶段, NextBitmap 和 PrevBitmap 会交换位置:


所以,我们的图就变成了下面的样子:


可以看到,NextBitmap 和 PrevBitmap 交换了位置,NextTAMS 和 PrevTAMS 交换了位置。


而 Region 中, Bitmap 白色部分对应的已使用内存变成了浅灰色。它仅仅是标记了出来,并没有进行清扫操作。


需要注意的是:清理阶段不拷贝任何对象


引用R大的回答来描述这个阶段:


清点和重置标记状态。这个阶段有点像 mark-sweep 中的 sweep 阶段,不过不是在堆上 sweep 实际对象,而是在 marking bitmap 里统计每个 Region 被标记为活的对象有多少。这个阶段如果发现完全没有活对象的 Region 就会将其整体回收到可分配 Region 列表中。


好了,到这里我们就能把前面的那张图给填上了:



然后再看一下论文中的这张图片,你就会发现,我上面的过程都是基于这张图片去分析的,图中展示了两个循环, A-B-C , D-E-F 。其中 E、F 过程就是 B、C 过程的重复:


我让上面的图片动起来,请细细品。请注意各个阶段 PrevTAMS 、 NextTAMS 指针的交换、 PrevBitmap 和 NextBitmap 位置的交换:


如果一次看不懂,就再看一次。看的时候结合上面的长图和动图一起分析,效果更佳。



参考资料:


1.https://max.book118.com/html/2018/0815/7043143036001143.shtm


2.https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/G1GettingStarted/index.html


3.https://www.oracle.com/technetwork/java/javase/tech/g1-intro-jsp-135488.html


4.https://www.infoq.com/articles/G1-One-Garbage-Collector-To-Rule-Them-All/


5.https://hllvm-group.iteye.com/group/topic/44381


6.《深入理解Java虚拟机(第三版)》


最后说一句(求关注)


本文是对《面试官:你说你熟悉jvm?那你讲一下并发的可达性分析》这篇文章的补充说明。如果你没看过,我建议你去看看。


我觉得有些知识点仅仅靠文章和图片是很难说清楚的,所以我费劲的做了动图。


为了做这篇文章和上篇文章中的几张动图,加起来我截了 80 多张图。你知道我为了把每张图截的一个像素都不差,我有多努力吗?


截的我眼球布满了血丝,眼睛都快瞎了,你不关注一波?


我四级半的英语水平,为了文章的正确性,强行啃英文论文,你不感动吗?


点个关注呀,别白嫖我啊,大哥。写文章很辛苦的,需要来点正反馈。


才疏学浅,难免会有纰漏,如果你发现了错误的地方,还请你留言给我指出来,我对其加以修改。


感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。


我是why技术,一个不是大佬,但是喜欢分享,又暖又有料的四川好男人。

以上。


欢迎关注公众号【why技术】,坚持输出原创。分享技术、品味生活,愿你我共同进步。

目录
相关文章
|
2月前
|
存储 监控 算法
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程 ?
尼恩提示: G1垃圾回收 原理非常重要, 是面试的重点, 大家一定要好好掌握
美团面试:说说 G1垃圾回收 底层原理?说说你 JVM 调优的过程  ?
|
5月前
|
Java
Java面试题:什么是G1垃圾收集器,它如何改善性能?
Java面试题:什么是G1垃圾收集器,它如何改善性能?
55 0
Java 最常见的面试题:怎么判断对象是否可以被回收?
Java 最常见的面试题:怎么判断对象是否可以被回收?
|
存储 缓存 算法
13-大厂面试题:为什么要垃圾回收以及如何判断对象可以回收
接下来我们正式进入第二个系列,关于垃圾回收以及优化。
110 0
13-大厂面试题:为什么要垃圾回收以及如何判断对象可以回收
|
7月前
|
存储 算法 Java
[Java 源码] 秋招常被问到 GC 相关的几道面试题(集中在分配以及回收)
[Java 源码] 秋招常被问到 GC 相关的几道面试题(集中在分配以及回收)
|
7月前
|
监控 Java 程序员
GC(垃圾处理机制)面试加薪必备
GC(垃圾处理机制)面试加薪必备
56 0
|
存储 Java
【面试题精讲】JVM-方法区的回收
【面试题精讲】JVM-方法区的回收
|
算法 Java
【面试题精讲】为什么G1收集器不需要调优性能也很优秀
【面试题精讲】为什么G1收集器不需要调优性能也很优秀
|
算法 Java
第二季:1.JVM垃圾回收的时候如何确定垃圾?是否知道什么是GC Roots【Java面试题】
第二季:1.JVM垃圾回收的时候如何确定垃圾?是否知道什么是GC Roots【Java面试题】
102 0
|
存储 SQL 机器学习/深度学习
面试官:你这数据库表设计的,真垃圾。。。
面试官:你这数据库表设计的,真垃圾。。。