何时触发Full GC?

14

据我理解:

Minor GC

在 young gen 中发生的 GC 通常称为 Minor GC,因为 live-set 通常很小(我是指典型的 Java 应用程序,考虑到弱代假说),并且使用较少数量的对象进行复制和重映射的收集器需要 较短 的时间来完成。

Major GC

在 old gen 中发生的 GC 通常称为 Major GC,因为 live-set 通常很大(与 young gen 相比),它通常会压缩 old gen,并且随着 old generation 大小的线性增加,整理所需的时间也会相应增加。

不幸的是,GC 日志将 old generation 收集报告为 Full GC,但在 Java 内存管理白皮书中,全堆 GC 指整个堆都被收集。

A Full GC will be triggered whenever the heap fills up. In such a case the 
young generation is collected first followed by the old generation. If the 
old generation is too full to accept the content of the young generation,
the young generation GC is omitted and the old generation GC is used to 
collect the full heap, either in parallel or serial. Either way the whole 
heap is collected with a stop-the-world event.

如果年轻代填满时总是会发生 Minor GC,老年代填满时总是会发生 Major GC,那么所谓的 Full GC 会在什么时候发生呢?如果年轻代和老年代收集器都在做其工作,为什么堆还会变满呢?


1
这个主题的有用视频:GC调优和故障排除速成课程 - codeforester
2个回答

10
当区域大小发生变化时,会在年轻代和老年代都进行垃圾回收的情况下进行完整的GC。
例如,如果我们提到:
-Xms1024m -Xmx2048m -XX:PermSize=512m -XX:MaxPermSize=1024m
JVM最初使用1GB堆,但从操作系统中保留了2GB的空间。因此,根据VM人体工程学,当这些区域的使用量增加时,年轻代和老年代将被调整大小,直到达到2GB的最大保留大小。
同样的事情也适用于PermSize,每次PermGen调整大小时,都会发生完整的GC。

2

Full GC - 我们已经知道,它会同时收集Young Gen SpaceOld Gen Space

何时触发?

我将解释两种情况

1. 对老年代更快的对象分配/晋升速率

假设CMS正在老年代空间中运行。与此同时,由于MINOR GC在young gen space中运行的速度比CMS操作要快得多,因此越来越多的对象被提升到old gen space。所以,

GC算法预测并发收集不会在堆变满之前结束,因此它决定停止所有操作并运行FULL GC。

2. 晋升失败

什么是晋升失败?——这与在堆中从年轻代向老年代空间晋升对象时的失败有关。

假设MINOR GC在young gen space中运行,并尝试将对象晋升到old gen space,如果old gen没有足够的连续空间来容纳该对象,则会导致晋升失败。

如果出现晋升失败,将会触发完全垃圾回收(FULL GC)。这并不会调用CMS垃圾回收,因为晋升失败的主要原因是内存碎片。由于CMS无法解决内存碎片问题,所以完全垃圾回收是最佳选择。

如果在晋升失败期间老年代空间正在运行CMS,则会导致并发模式失败,并且当然会运行完全垃圾回收。


能否分享一些支持你得出这些结论的参考资料?谢谢! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接