1. 程式人生 > 其它 >Young GC和Full GC分別在什麼情況下會發生

Young GC和Full GC分別在什麼情況下會發生

Young GC的觸發時機

Young GC其實一般就是在新生代的Eden區域滿了之後就會觸發,採用複製演算法來回收新生代的垃圾

Old GC和Full GC的觸發時機

下面幾種情況:

(1)發生Young GC之前進行檢查,如果“老年代可用的連續記憶體空間” < “新生代歷次Young GC後升入老年代的物件總和的平均大小”,說明本次Young GC後可能升入老年代的物件大小,可能超過了老年代當前可用記憶體空間。
此時必須先觸發一次Old GC給老年代騰出更多的空間,然後再執行Young GC。

(2)執行Young GC之後有一批物件需要放入老年代,此時老年代就是沒有足夠的記憶體空間存放這些物件了,此時必須立即觸發一次Old GC

(3)老年代記憶體使用率超過了92%,也要直接觸發Old GC,當然這個比例是可以通過引數調整的其實說白了,上述三個條件你概括成一句話,就是老年代空間也不夠了,沒法放入更多物件了,這個時候務必執行Old GC對老年代進行垃圾回收。
順便說一句,大家在很多地方看到一個說法,意思是說Old GC執行的時候一般都會帶上一次Young GC

可能很多人不理解,其實如果你把咱們這裡的幾個條件分析清楚了就知道了,一般Old GC很可能就是在Young GC之前觸發或者在Young GC之後觸發的,所以自然Old GC一般都會跟一次Young GC連帶關聯在一起了。

另外一個,在很多JVM的實現機制裡,其實在上述幾種條件達到的時候,他觸發的實際上就是Full GC,這個Full GC會包含Young GC、Old GC和永久代的GC。

也就是說觸發Full GC的時候,可能就會去回收年輕代、老年代和永久代三個區域的垃圾物件。

但是這個東西其實沒辦法給大家一個準確的定義,說到底觸發Full GC的時候,是先執行Young GC?還是先執行Old
GC。

因為不同的Full GC觸發條件其實是不一樣的,而且不同的JVM版本的實現機制也不同。

所以很多時候,我們也只能給大家籠統的概括一句:上述條件滿足時觸發Full GC,Full GC一般會帶上一次Young GC去回收新生代,同時也會有Old GC也回收老年代,還會去回收永久代。

永久代滿了之後怎麼辦

大家現在既然都知道了,Full GC有上述幾個觸發條件,同時觸發Full GC的時候其實會帶上針對新生代的Young GC,也會有針對老年代的Full GC,還會有針對永久代的GC。

所以假如存放類資訊、常量池的永久代滿了之後,就會觸發一次Full GC。這樣Full GC執行的時候,就會順帶把永久代中的垃圾給回收了,但是永久代中的垃圾一般是很少的,因為裡面存放的都是一些類,還有常量池之類的東西,這些東西通常來說是不需要回收的。

如果永久代真的放滿了,回收之後發現沒騰出來更多的地方,此時只能丟擲記憶體不夠的異常了。