为什么JVM完整GC需要停止世界?

时间:2013-05-22 15:32:03

标签: garbage-collection jvm

我被问到这个问题,我刚刚回答“因为JVM需要移动对象”,但后来我用Google搜索,似乎找不到任何合理的答案。

4 个答案:

答案 0 :(得分:64)

首先,Garbage Collection article at wikipedia非常好读。

说到。

一般情况下,GC不需要Stop-the-World暂停。 有(几乎)暂停的JVM实现(例如Azul Zing JVM)。每当JVM要求STW收集垃圾时,都依赖于它正在使用的算法。

Mark Sweep Compact(MSC)是默认情况下HotSpot中使用的流行算法。它以STW方式实施,分为三个阶段:

  • MARK - 遍历实时对象图以标记可到达的对象
  • SWEEP - 扫描内存以查找未标记的内存
  • COMPACT - 重新定位标记对象以对可用内存进行碎片整理

在堆中重定位对象时,JVM应该更正对该对象的所有引用。在重定位过程中,对象图不一致,这就是需要STW暂停的原因。

并发标记扫描(CMS)是HotSpot JVM中的另一种算法,它不会对旧空间集合使用STW暂停(与完整集合不完全相同)。

CMS正在利用写屏障(每次在Java堆中编写引用时触发)以实现MARK的并发版本并且不使用COMPACT。缺乏压缩可能导致碎片,如果后台垃圾收集速度不够快,仍然可以阻止应用程序。在这些情况下,CMS将回退到STW mark-sweep-compact集合。

还有 G1 ,这是MSC的增量变异。您可以在我的博客中阅读有关GC algorithms in HotSpot JVM的更多信息。

答案 1 :(得分:9)

使用吞吐量GC,JVM需要STW暂停才能获得尽可能多的内存。只是使用这种停顿才是最有效的。

使用低暂停收集器(CMS),可以同时清理旧代,而不会暂停应用程序。缺点是老一代变得支离破碎。如果它太碎片并且需要压实,则会发生Full GC(STW)。但是,您始终可以调整应用程序,以便不会获得任何Full GC。

G1 GC是一个特例。它目前的主要目标是在堆上具有低碎片,同时仍然是并发(如CMS)。当它无法达到此目标时,JVM也会恢复为STW暂停,以便完全清理和压缩堆。

答案 2 :(得分:0)

stop-the-world保证在收集器运行时不会分配新对象,并且对象不会突然变得无法访问。

优点是它实现起来既简单又比增量垃圾收集更快。

答案 3 :(得分:0)

在几乎所有垃圾收集方案中都需要一个简短的停止世界阶段来扫描堆栈上的引用,即使在大多数最小化暂停的方案中也是如此。 this answer中的详细解释。 增量和并发算法努力将这些暂停降至最低,但在大多数情况下仍然存在。

实际上甚至有移动/压缩方法在移动物体时不需要停止世界(Staccato浮现在脑海中)