JAVA: CMS垃圾回收中的“浮动垃圾”的理解?

书上说:并发清理阶段用户线程还在运行,这段时间就可能产生新的垃圾,新的垃圾在此次GC无法清除,只能等到下次清理。这些垃圾有个专业名词:浮动垃圾。

这个浮动垃圾如何理解?难道不是在本次GC重新标记remark的过程中被发现然后清理吗?为何还要等下次GC才能清理?

阅读 19.8k
4 个回答

重新标记(Remark) 的作用在于:
之前在并发标记时,因为是 GC 和用户程序是并发执行的,可能导致一部分已经标记为 从 GC Roots 不可达 的对象,因为用户程序的(并发)运行,又可达 了,Remark 的作用就是将这部分对象又标记为 可达对象


至于 “浮动垃圾”,因为 CMS并发标记 时是并发的,GC 线程和用户线程并发执行,这个过程当然可能会因为线程的交替执行而导致新产生的垃圾(即浮动垃圾)没有被标记到;而 重新标记 的作用只是修改之前 并发标记 所获得的不可达对象,所以是没有办法处理 “浮动垃圾” 的。

remark过程标记活着的对象,从GCRoot的可达性判断对象活着,但无法标记“死亡”的对象。
如果在初始标记阶段被标记为活着,并发运行过程中“死亡”,remark过程无法纠正,因此变为浮动垃圾,需等待下次gc的到来。

谢邀。仅仅说说自己的理解:

  • 如果浮动垃圾不停的产生,那么是不是一直不GC,一直做remark了..这样会造成OOM的。

重新标记阶段只会利用增量更新来解决因并发标记阶段产生的对象消失问题,而浮动垃圾的产生原因是因为已经被GC线程被标记为黑色了,但用户线程接着又取消了对它的所有引用,但是黑色对象并不会被重新扫描,所以重新标记是找不到浮动垃圾的,就算能解决,并发清理阶段一样会产生浮动垃圾,而并发清理已经是最后一个阶段了,所以浮动垃圾只能下次垃圾回收的时候才能被回收

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题