瞭解JVM發生GC的原因以及過程,纔可以更加針對的對虛擬機進行內存分配,從而減少full gc,避免造成系統卡頓甚至系統崩潰
FULL GC帶來的危害(STW)
在發生FULL GC的時候,意味着JVM會安全的暫停所有正在執行的線程(Stop The World),來回收內存空間,在這個時間內,所有除了回收垃圾的線程外,其他有關JAVA的程序,代碼都會靜止,反映到系統上,就會出現系統響應大幅度變慢,卡機等狀態
JVM的堆內存空間
- Eden(伊甸園)區域:用來存放使用new或者newInstance等方式創建的對象,默認這些對象都是存放在Eden區,除非這個對象太大,或者超出了設定的閾值-XX:PretenureSizeThresold,這樣的對象會被直接分配到Old區域。
- 2個Survivous(倖存)區域:一般稱爲S0,S1或者From Survivous,To Survivous ,理論上他們一樣大。
第一次GC(minor GC)
當不斷地創建對象,當Eden區域佔滿的時候,此時開始做Young GC也叫做Minor GC,第一次GC時Survivous中S0區和S1區都爲空,Eden區域執行GC後不能被回收的對象->S0,若進入S0區域的對象大小超過S0區域的閾值,則直接進入old區域,等等
第二次GC(minor GC)
當第二次Eden區域被佔滿時,此時開始做GC,將Eden和From Survivous(S0)中經過GC未被回收的對象遷移到To Survivous(S1),等等
以次類推,始終保證S0和S1有一個空的,用來存儲臨時對象,用於交換空間的目的。反反覆覆多次沒有被淘汰的對象,將會被放入Old區域中,默認15次(由參數--XX:MaxTenuringThreshold=15 決定)
綜合上述的過程可知S0和S1的區域分配的空間一定要大小合適,避免一個對象大於S0或者S1區域的閾值,導致直接進入Old區域