簡體   English   中英

什么時候觸發 Full GC?

[英]When is a Full GC triggered?

按照我的理解:

次要GC

發生在年輕代的 GC 通常被稱為 Minor,因為它需要更少的時間來完成,因為 live-set 通常很小(我說的是典型的 java 應用程序,考慮到弱世代假設)和一個數量較少的復制收集器要重新定位和重新映射的對象。

主要GC

發生在老一代中的 GC 通常稱為 Major GC,因為它需要更多的時間來完成,因為 live-set 大部分是大的(與年輕代相比)並且它通常會壓縮老一代,並且壓縮時間隨着老年代大小。

不幸的是,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 什么時候發生? 如果年輕一代和老一代收集器都在盡自己的一份力,堆怎么會變滿?

當區域大小發生變化時,會發生年輕代和年老代都被收集的 Full GC。

例如,如果我們提到

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

JVM 最初以 1GB 的堆開始,但為操作系統保留了 2GB 的空間。 因此,隨着這些區域使用量的增加,基於 VM 的人體工程學,年輕代和年老代會被調整大小,直到它們達到 2GB 的最大保留大小。

同樣的事情也適用於 PermSize,每次 PermGen 調整大小時,都會發生完整的 GC。

Full GC - 我們已經知道,它同時收集Young Gen SpaceOld Gen Space

什么時候觸發?

我將解釋兩個場景

1. 更快的對象分配/提升到老年代的速度

假設 CMS 在舊的 gen 空間中運行。 同時,由於在年輕代空間中運行的 MINOR GC 比 CMS 運行的速度快得多,因此越來越多的對象被提升到老年代空間。 所以,

GC 算法預測並發收集不會在堆滿之前結束,因此它決定停止一切並運行FULL GC。

2. 促銷失敗

什么是促銷失敗? - 這與將對象從堆中的較年輕代空間提升到較舊代空間時失敗有關。

假設 MINOR GC 在年輕代空間中運行並嘗試將對象提升到老代空間,如果老代沒有足夠的連續空間來容納對象,則會導致提升失敗。

升級失敗將要求運行FULL GC 它不要求 CMS GC,因為發生促銷失敗的主要原因是碎片。 由於 CMS 不會解決碎片問題,FULL GC 是首選。

如果假設 CMS 在升級失敗期間在舊代空間中運行,則將導致並發模式失敗,當然會運行 FULL GC。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM