什么时候触发 Full GC?

据我了解:

次要 GC

发生在年轻一代的 GC 通常称为 Minor,因为它需要 更少 时间来完成,因为 live-set 通常很小(我说的是典型的 Java 应用程序,考虑到弱世代假设)和一个复制收集器,需要重新定位和重新映射的对象数量较少.

a GC that happens in the young gen is usually called Minor because it takes less time to complete as the live-set will be usually small (i'm talking about typical java application considering the weak generational hypothesis) and a copying collector with less number of objects to relocate and remap.

主要 GC

发生在老一代的 GC 通常称为 Major GC,因为它需要 更多 时间来完成,因为 live-set 大部分都很大(与年轻一代相比)并且它通常会压缩老一代gen 和 compaction 的时间随着老年代的大小线性增加.

a GC that occurs in the old gen is usually called Major GC because it takes more time to complete as live-set will be mostly big (compared to young gen) and it usually compacts the old gen and the time for compaction increases linearly with the old generation size.

不幸的是,GC 日志将老年代收集报告为 Full GC,而只有老年代被收集.但是在 java 内存管理白皮书中有一个 Full GC 的概念,其中收集了整个堆.

Unfortunately the GC logs report the old generation collection as Full GC while it's only the Old generation that's being collected. But in java memory management white paper there's a notion of Full GC in which the entire heap is collected.

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 什么时候会发生?如果年轻一代和老一代收集器都在做自己的事情,堆怎么会变满?

If there's always a Minor GC when the young gen fills up and if there's always a Major GC when the old gen fills up, when will this so called Full GC happen? How come the heap becomes full if both the young gen and old gen collectors are doing their part?

推荐答案

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

A Full GC where in both the young and old generations are collected occurs when there's change in region size.

例如,如果我们提到

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

JVM 最初从 1GB 堆开始,但从 OS 保留 2GB 空间.因此,随着这些区域的使用量增加,根据 VM 人体工程学,年轻代和年老代会调整大小,直到它们达到 2GB 的最大保留大小.

JVM initially starts with 1GB of heap but reserves space for 2GB from OS. So as the usage of these regions increases, based on VM ergonomics, Young and old generations are resized until they reach the max reserved size of 2GB.

同样的事情也适用于 PermSize,每次 PermGen 调整大小时,都会发生一次完整的 GC.

Same thing applies for PermSize as well, every time PermGen resizes, a full GC will occur.

相关文章