面试官:你回去等通知吧! (下)

简介: 面试官:你回去等通知吧! (下)

你是什么时候的垃圾-勘误


在《G1回收器:我怎么知道你是什么时候的垃圾?》这篇文章中有一句描述是这样的:


“GC Roots 能直接关联到的对象:就是一个 Region 已经使用过的部分,所以在 bottom 与 top 之间。”这句话是错误的。


实际上,通过文章后面的描述你也能发现。GC Roots 能直接关联到的对象集合应该“小于” Region 已经使用过的部分,对象图递归完之后,所有对象总和,才等于Region已经使用过的部分。


通过文章中后半部分的这个图片也可以直观的发现, bottom 到 top 之间是一个 Region 已经使用的部分。但是这一部分中,只有 bottom 到 NextTAMS 之间的对象才是 GC Roots 能直接关联到的对象,这部分对象并不是一个 Region 已经使用过的部分。


你是什么时候的垃圾-补充说明


关于《G1回收器:我怎么知道你是什么时候的垃圾?》这篇文章,还有两个需要补充说明的地方。


有的读者问说:文章中没有讨论回收的内容,每次清理不会真正回收,那是不是多轮标记后才发生一次回收呢?


一。


首先,文章中确实没有讨论回收相关的内容。我在前面部分也写了,把G1回收切分为两大部分:


1.Global Concurrent Marking:全局并发标记。


2.Evacuation Pauses:该阶段是负责把一部分Region里的活对象拷贝到空Region里面去,然后回收原本的Region空间。


只要清楚了全局并发标记阶段,就可以解答文中抛出的这个问题:


所以我只说明了全局并发标记阶段。


如果想要了解回收阶段的事,可以去看看R大的回答,强烈建议你看完本文,点个赞后,打开下面的链接,反复阅读几遍:


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

其次,“每次清理不会真正回收,那是不是多轮标记后才发生一次回收呢?”


这句话,可能是我在文章强调了清理阶段不拷贝任何对象,再加上没有描述回收阶段,导致读者有点懵了吧。


一次全局并发标记完成后,紧接着一次回收的过程。


只是G1收集器之所以能建立可预测的停顿时间模型(-XX:MaxGCPauseMillis指定,默认值为200毫秒),是因为它将 Region 作为单次回收的最小单元,即每次收集到的内存空间都是 Region 大小的整数倍,这样就可以有计划地避免在整个Java堆中进行全区域的垃圾回收。


更具体一点的做法就是每个 Region 里面堆积的垃圾都有一个“价值”(价值即回收所获得的空间大小以及回收所需要的时间的经验值)。而这些“价值”,是维护在一个优先级列表中的,G1收集器都是知道的。


所以回收阶段会优先处理回收价值最大的那些 Region。因此,一次回收的过程并不会回收所有的 Region。


二。


这里也就解释了读者提出的另外一个问题:如果每次标记完都会回收整理,那为什么红框所在的区间与上一次标记之后相同,好像没有被整理一样,整理之后不是应该不留下内存空隙吗?


我觉得一个合理的解释,就是我上面说的:这个 Region 的价值不够,所以它本次没有被回收。随着时间的推移,它里面堆积的垃圾越来越多,“价值”就越来越高,总是会被回收的。


还有读者问:看了并发标记的过程,有个疑问 prevBitmap 的作用是什么? 因为感觉每次都是从头开始扫描,没看到它的作用。


这个问题,可以从这张图片入手解答:


这个 E 是 Remark 阶段,可以看到,在这个阶段,其实 PrevBitmap 是派上用场了。


前面刚刚说了,这个 Region 由于“价值”不够,它逃过了上次垃圾回收,所以待到下次垃圾回收的时候,就是 prevBitmap 的用武之地了,它里面记录的地址对应的区间就不需要再次标记了,因为这些地址对应的对象就已经是垃圾了。


我们可以假设 E 代表的是第 n 轮回收的过程的Remark阶段。那么 PrevBitmap 就是第 n-1 轮的标记结果。


之前的文章说了:一个 previous Bitmap 记录的是上一轮 Concurrent Marking 后的对象标记状态,因为上一轮已经完成(上一轮就是第n-1轮),所以这个bitmap的信息可以直接使用。


可以直接使用的意思就是前面说的:它里面记录的地址对应的区间就不需要再次标记了,因为这些地址对应的对象就已经是垃圾了。


到 F 图里面,可以看到,当前的 F 图是清理阶段已经完成的状态了:


判断标准有二:


1.和 E 图相比PrevBitmap 和 NextBitmap 已经交换了位置。


2.PrevBitmap 里面对应的地址的空间已经被标记为浅灰色了。


这个时候已经完成标记,PrevBitmap 又变成了第n-1次标记的结果。


你是什么垃圾-怼人


因为之前的文章已经发布了,所以我需要修改一下对应的内容。提醒后面的读者,如果看到了文章,需要注意这些地方描述的有问题。


但是我在查找我文章的过程中发现了一些让我很郁闷的事情,之前的文章,大都被剽窃了,我也见怪不怪,有时间就顺手举报一下了。

最过分的是下面这个:


这是一个百家号账号,一字不差的抄我文章,还自己标注为“原创”?

我去写了个评论:


他还不敢把评论放出来。


还有下面这个,你可长点心吧。你配的这张图片,我倒是想在家拍,但是我拍不出来呀:


这样的情况还有很多。说到底,就还是版权意识的问题。

版权问题,我之前在《订阅号做了77天,我挣了487.52元》这篇文章里面聊过:


我的号不会传播任何盗版资源,以前如此,现在如此,以后也会如此。

不做恶,就是最大的善。与君共勉。


所以我在此郑重声明,如果未经许可转载我的文章,必须标明原文地址,且保留文末公众号二维码,否则我一定见一个举报一个。


我先举报你涉黄,引起工作人员的注意,再举报你抄袭,让工作人员惩罚你。

气死我了。


最后说一句(求关注)


通过这件事我也再次感觉到了,看网上的野生文章(比如我的),要持有谨慎、怀疑、学习的态度。


才疏学浅,难免会有纰漏,如果你发现了错误的地方,还请你留言给我指出来,我对其加以修改。(我每篇技术文章都有这句话,我是认真的说的。)


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


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

以上。


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


目录
相关文章
|
3月前
|
前端开发 JavaScript Java
v-for比v-if优先级更高?面试官:回去等通知吧
v-for比v-if优先级更高?面试官:回去等通知吧
|
4天前
|
Java
面试官让说出8种创建线程的方式,我只说了4种,然后挂了。。。
面试官让说出8种创建线程的方式,我只说了4种,然后挂了。。。
6 1
|
5月前
终于搞明白什么叫做回调了
终于搞明白什么叫做回调了
28 0
|
7月前
如何实现每天定时给女友/老婆发消息
如何实现每天定时给女友/老婆发消息
|
9月前
|
存储 算法 Java
面试官:回家等通知吧 <一>
面试官:回家等通知吧 <一>
|
SQL 消息中间件 前端开发
103. 面试技巧:面试的时候我只会聊项目,结果就把我挂了
103. 面试技巧:面试的时候我只会聊项目,结果就把我挂了
119 0
103. 面试技巧:面试的时候我只会聊项目,结果就把我挂了
|
消息中间件 存储 前端开发
面试官让我手写队列,差点没写出来,回来后赶忙把重点记下来
栈和队列是一对好兄弟,前面我们介绍过一篇栈的文章(栈,不就后进先出),栈的机制相对简单,后入先出,就像进入一个狭小的山洞,山洞只有一个出入口,只能后进先出(在外面的先出去,堵在里面先进去的就有点倒霉)。而队列就好比是一个隧道,后面的人跟着前面走,前面人先出去(先入先出)。日常的排队就是队列运转形式的一个描述!
88 0
面试官让我手写队列,差点没写出来,回来后赶忙把重点记下来
|
缓存 Java
学会这些,再也不怕面试被问线程知识了
继承Thread类创建线程,重写run方法,实现Runnable接口创建线程,实例化thread类,使用Callable和Future创建线程,使用线程池例如用Executor框架
89 0
|
SQL JavaScript Java
新来的同事问我 where 1=1 是什么意思
新来的同事问我 where 1=1 是什么意思
新来的同事问我 where 1=1 是什么意思
|
SQL 关系型数据库 MySQL
新来的同事问我 where 1=1 是什么意思。。还有谁不会?
新来的同事问我 where 1=1 是什么意思。。还有谁不会?
新来的同事问我 where 1=1 是什么意思。。还有谁不会?