我认为是因为JVM需要移动对象,这正确吗?
我认为是因为JVM需要移动对象,这正确吗?
首先,维基百科的垃圾回收文章非常好阅读。
一般来说,GC不需要Stop-the-World暂停。有些JVM实现几乎是无暂停的(例如Azul Zing JVM)。JVM何时需要STW来收集垃圾取决于它所使用的算法。
Mark Sweep Compact(MSC)是默认在HotSpot中使用的流行算法。它以STW方式实现,具有3个阶段:
在堆中重定位对象时,JVM应该更正对该对象的所有引用。在重定位过程中,对象图不一致,这就是为什么需要STW暂停的原因。
Concurrent Mark Sweep(CMS)是另一个HotSpot JVM中的算法,它不为老年代收集(不完全与全集合相同)使用STW暂停。
CMS利用写屏障(每次在Java堆中写入引用时触发的触发器)来实现MARK的并发版本,不使用COMPACT。缺乏压缩可能会导致碎片化,如果后台垃圾收集不够快,应用程序仍然可能被阻塞。在这些情况下,CMS将回退到STW标记-扫描-压缩收集。
还有G1,它是MSC的增量变体。您可以在我博客中阅读更多有关HotSpot JVM中的GC算法。
使用吞吐量GC,JVM需要STW暂停来释放尽可能多的内存。只有使用这样的暂停,它才是最有效的。
使用低暂停收集器(CMS),您可以同时清理老年代空间,而无需暂停应用程序。缺点是老年代变得分散。如果它过于分散并且需要压缩,则会发生Full GC(STW)。但是,您始终可以调整应用程序以使其不产生任何Full GC。
G1 GC是一个特例。它当前的主要目标是在堆上具有低碎片化,同时仍然是并发的(就像CMS一样)。当它无法达到此目标时,JVM也会回到STW暂停,以便堆完全清理和压缩。