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執行的時候,就會順帶把永久代中的垃圾給回收了,但是永久代中的垃圾一般是很少的,因為里面存放的都是一些類,還有常量池之類的東西,這些東西通常來說是不需要回收的。
如果永久代真的放滿了,回收之后發現沒騰出來更多的地方,此時只能拋出內存不夠的異常了。