【问题标题】:Major Garbage collection with Concurrent Mark Sweep Collector?使用并发标记清除收集器进行主要垃圾收集?
【发布时间】:2025-12-06 13:30:01
【问题描述】:

我已经通过这个Link 并得到了一些 关于 Major Garbage collection 和 Parallel collector 的问题

问题1:-

链接说 “通常一个主要的集合要慢得多,因为它涉及所有活动对象”,我不明白如何 处理活动对象会使主要收集比较慢 次要收集适用于无法访问的对象的混合 和活的物体。

问题2:-

Link 说 “主要的垃圾收集也是 Stop the World 事件”

另一方面,它说 “CMS 收集器尝试通过与应用程序线程同时执行大部分垃圾收集工作来尽量减少由于垃圾收集而导致的暂停” CMS 收集器也会停止主应用程序线程,直到它完成或与应用程序线程同时运行

问题3:-

由于有对象从 eden >(Minor GC) 幸存者 >(Minor GC) 老年代 > (Major GC) > 清理老年代并压缩它。

据我了解,当对象从幸存者移动到老年代或压缩时,对象内存位置会发生变化 完成major GC(虽然对象的内存位置在它移动到幸存者空间时没有改变)

【问题讨论】:

  • 我个人会阅读this white paper,它非常全面,应该能回答你所有的问题。

标签: java memory-management garbage-collection


【解决方案1】:

对于并发标记扫描:

  1. 这里的关键词是all。 “主要收集要慢得多,因为它涉及 所有 活动对象。”不是一次只有几个,而是全部。

  2. CMS 通常与应用程序同时运行,但当堆太满或碎片过多时,整个程序会暂停,以便对所有垃圾进行完整的垃圾回收。这真的很慢,因为所有垃圾都被收集了,而且运行速度甚至比您预期的还要慢,因为主要收集是单线程。无论您的机器有多少个内核,在主要收集期间,其中一个内核上只有一个线程可以为 Java 做任何工作。

  3. CMS 通常不会四处移动对象,除非在主要收集期间。 CMS 可以同时运行,因为它所做的只是释放死对象。但这可能会导致大量碎片,如果堆中没有足够大的“洞”来容纳正在创建的大型新对象,CMS 将停止世界并进行主要收集。其中一部分是压缩整个堆,并将堆中的所有对象移动到它的一端,从而在堆的另一端形成最大的“洞”以进行新的分配。

【讨论】: