书上说:并发清理阶段用户线程还在运行,这段时间就可能产生新的垃圾,新的垃圾在此次GC无法清除,只能等到下次清理。这些垃圾有个专业名词:浮动垃圾。
这个浮动垃圾如何理解?难道不是在本次GC重新标记remark的过程中被发现然后清理吗?为何还要等下次GC才能清理?
这个浮动垃圾如何理解?难道不是在本次GC重新标记remark的过程中被发现然后清理吗?为何还要等下次GC才能清理?
remark过程标记活着的对象,从GCRoot的可达性判断对象活着,但无法标记“死亡”的对象。
如果在初始标记阶段被标记为活着,并发运行过程中“死亡”,remark过程无法纠正,因此变为浮动垃圾,需等待下次gc的到来。
重新标记阶段只会利用增量更新来解决因并发标记阶段产生的对象消失问题,而浮动垃圾的产生原因是因为已经被GC线程被标记为黑色了,但用户线程接着又取消了对它的所有引用,但是黑色对象并不会被重新扫描,所以重新标记是找不到浮动垃圾的,就算能解决,并发清理阶段一样会产生浮动垃圾,而并发清理已经是最后一个阶段了,所以浮动垃圾只能下次垃圾回收的时候才能被回收
15 回答8.4k 阅读
8 回答6.2k 阅读
1 回答4k 阅读✓ 已解决
3 回答6k 阅读
3 回答2.2k 阅读✓ 已解决
2 回答3.1k 阅读
2 回答3.8k 阅读
重新标记(Remark) 的作用在于:
之前在并发标记时,因为是 GC 和用户程序是并发执行的,可能导致一部分已经标记为 从 GC Roots 不可达 的对象,因为用户程序的(并发)运行,又可达 了,Remark 的作用就是将这部分对象又标记为 可达对象。
至于 “浮动垃圾”,因为 CMS 在 并发标记 时是并发的,GC 线程和用户线程并发执行,这个过程当然可能会因为线程的交替执行而导致新产生的垃圾(即浮动垃圾)没有被标记到;而 重新标记 的作用只是修改之前 并发标记 所获得的不可达对象,所以是没有办法处理 “浮动垃圾” 的。