何时触发完整GC



根据我的理解:

<<p> 较小的GC/strong>

发生在年轻代中的GC通常被称为Minor,因为它需要更少的时间来完成,因为活动集通常很小(我谈论的是考虑弱分代假设的典型java应用程序),并且复制收集器具有更少的对象来重新定位和重新映射。

主要GC

在旧代中发生的GC通常被称为主GC,因为它需要更多的时间来完成,因为活集将大部分很大(与年轻代相比),它通常会压缩旧代,并且压缩时间随着旧代的大小线性增加。

不幸的是,GC日志报告旧代收集为Full GC,而它只是旧代收集。但是在java内存管理白皮书中有一个Full 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 ?如果年轻代和老代收集器都在做自己的工作,为什么堆会满呢?

当区域大小发生变化时,会同时收集年轻代和老代。

例如,如果我们提到

-Xms1024m -Xmx2048m -XX:PermSize=512m -XX:MaxPermSize=1024m

JVM最初有1GB的堆,但从操作系统保留2GB的空间。因此,随着这些区域的使用增加,基于VM人机工程学,Young和old代将调整大小,直到它们达到最大保留大小2GB。

同样的事情也适用于PermSize,每次PermGen调整大小,将发生一个完整的GC

完整GC -我们已经知道,它收集年轻代空间旧代空间

何时触发?

我将解释两种情况

1。更快的对象分配/提升率到老一代

假设CMS在旧的生成空间中运行。与此同时,越来越多的对象被提升到旧的根空间,因为MINOR GC在年轻的根空间中运行的速度比CMS运行的速度快得多。

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

2。促销失败

什么是促销失败?-这与在堆中将对象从年轻代空间提升到老代空间时失败有关。

假设MINOR GC在年轻的根空间中运行,并试图将对象提升到旧的根空间,如果旧的根没有足够的连续空间容纳该对象,则会导致提升失败。

升级失败将调用FULL GC运行。它不调用CMS GC,因为发生促销失败的主要原因是碎片。因为CMS不能解决碎片问题,所以FULL GC是一个选项。

如果假设CMS在升级失败期间运行在旧的根空间,它将导致并发模式失败,当然会运行一个完整的GC。

最新更新