先解釋YGC:
當對象生成在EDEN區失敗時,出發一次YGC,先掃描EDEN區中的存活對象,進入S0區,S0放不下的進入OLD區,再掃描S1區,若存活次數超過閥值則進入OLD區,其它進入S0區,然后S0和S1交換一次。
那么當發生YGC時,JVM會首先檢查老年代最大的可用連續空間是否大於新生代所有對象的總和,如果大於,那么這次YGC是安全的,如果不大於的話,JVM就需要判斷HandlePromotionFailure是否允許空間分配擔保。
允許分配擔保:
JVM繼續檢查老年代最大的可用連續空間是否大於歷次晉升到老年代的對象的平均大小,如果大於,則正常進行一次YGC,盡管有風險(因為判斷的是平均大小,有可能這次的晉升對象比平均值大很多);
如果小於,或者HandlePromotionFailure設置不允許空間分配擔保,這時要進行一次FGC。
新生代采用的是復制收集算法,S0和S1始終只是用其中一塊內存區,當出現YGC后大部分對象仍然存活的話,就需要老年代進行分配擔保,把survior區無法容納的對象直接晉升到老年代。
那么這種空間分配擔保的前提是老年代還有容納的空間,一共有多少對象會活下來,在實際完成內存回收之前是無法明確知道的,所以只好取之前每次回收晉升到老年代對象容量的平均值大小作為經驗值,與老年代的剩余空間比較,決定是否進行FGC來讓老年代騰出更多空間。