你是什么时候的垃圾-勘误
在《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技术】,坚持输出原创。分享技术、品味生活,愿你我共同进步。