1. 程式人生 > >Full GC

Full GC

onf 5.0 並發 net 滿了 執行c 發的 cms gc 反射

1,新生代:(1)所有對象創建在新生代的Eden區,當Eden區滿後觸發新生代的Minor GC,將Eden區和非空閑Survivor區存活的對象復制到另外一個空閑的Survivor區中。(2)保證一個Survivor區是空的,新生代Minor GC就是在兩個Survivor區之間相互復制存活對象,直到Survivor區滿為止。
2,老年代:當Survivor區也滿了之後就通過Minor GC將對象復制到老年代。老年代也滿了的話,就將觸發Full GC,針對整個堆(包括新生代、老年代、持久代)進行垃圾回收。
3,持久代:持久代如果滿了,將觸發Full GC。

full GC觸發的條件

除直接調用System.gc外,觸發Full GC執行的情況有如下四種。
1. 舊生代空間不足
舊生代空間只有在新生代對象轉入及創建為大對象、大數組時才會出現不足的現象,當執行Full GC後空間仍然不足,則拋出如下錯誤:
java.lang.OutOfMemoryError: Java heap space
為避免以上兩種狀況引起的FullGC,調優時應盡量做到讓對象在Minor GC階段被回收、讓對象在新生代多存活一段時間及不要創建過大的對象及數組。
2. Permanet Generation空間滿
PermanetGeneration中存放的為一些class的信息等,當系統中要加載的類、反射的類和調用的方法較多時,Permanet Generation可能會被占滿,在未配置為采用CMS GC的情況下會執行Full GC。如果經過Full GC仍然回收不了,那麽JVM會拋出如下錯誤信息:
java.lang.OutOfMemoryError: PermGen space
為避免Perm Gen占滿造成Full GC現象,可采用的方法為增大Perm Gen空間或轉為使用CMS GC。
3. CMS GC時出現promotion failed和concurrent mode failure
對於采用CMS進行舊生代GC的程序而言,尤其要註意GC日誌中是否有promotion failed和concurrent mode failure兩種狀況,當這兩種狀況出現時可能會觸發Full GC。
promotionfailed是在進行Minor GC時,survivor space放不下、對象只能放入舊生代,而此時舊生代也放不下造成的;concurrent mode failure是在執行CMS GC的過程中同時有對象要放入舊生代,而此時舊生代空間不足造成的。
應對措施為:增大survivorspace、舊生代空間或調低觸發並發GC的比率,但在JDK 5.0+、6.0+的版本中有可能會由於JDK的bug29導致CMS在remark完畢後很久才觸發sweeping動作。對於這種狀況,可通過設置-XX:CMSMaxAbortablePrecleanTime=5(單位為ms)來避免。
4. 統計得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩余空間
這是一個較為復雜的觸發情況,Hotspot為了避免由於新生代對象晉升到舊生代導致舊生代空間不足的現象,在進行Minor GC時,做了一個判斷,如果之前統計所得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩余空間,那麽就直接觸發Full GC。
例如程序第一次觸發MinorGC後,有6MB的對象晉升到舊生代,那麽當下一次Minor GC發生時,首先檢查舊生代的剩余空間是否大於6MB,如果小於6MB,則執行Full GC。
當新生代采用PSGC時,方式稍有不同,PS GC是在Minor GC後也會檢查,例如上面的例子中第一次Minor GC後,PS GC會檢查此時舊生代的剩余空間是否大於6MB,如小於,則觸發對舊生代的回收。
除了以上4種狀況外,對於使用RMI來進行RPC或管理的Sun JDK應用而言,默認情況下會一小時執行一次Full GC。可通過在啟動時通過- java-Dsun.rmi.dgc.client.gcInterval=3600000來設置Full GC執行的間隔時間或通過-XX:+ DisableExplicitGC來禁止RMI調用System.gc。

Full GC