理解JVM GC對於咱們把控Java應用有很大的幫助。下面我從運維角度,把網上的JVM相關的資料整理以下,以加深對JVM GC的理解。
若有錯誤的地方,請看官指正。算法
JVM內存使用分類多線程
JVM的內存分區關係:運維
關於年輕代、年老代、持久代jvm
對於JVM來講,內存分爲三個區域:年輕代、年老代和持久代。年輕代和年老代用來存放Java進程中的變量,持久代用於放Java類信息。
通常對咱們主要關注年輕代和年老代。JVM的分代能夠用下面這張圖表示:oop
年輕代分爲三個區域:一個Eden區(簡稱E區域),兩個Survivor區(咱們定義爲S0、S1)。
Java程序新申請的變量會放在E區;當E區滿時,全部存活的對象會被移動到S0區。當S0區滿時,S0中存活的對象被移動到S1區(這時候S0就空了,E區滿時存活的對象會移動到S1區)。當S1區滿時,將經歷過S0的對象移動到年老代(O區)。S0區和S1區是對等的,這樣一個對象要進入持久代會經歷E區、S0區、S1區,而後進入到O區。spa
年老代用於存放從年輕代晉升上來的對象(E區->S0區->S1區->O區),通常咱們設置的時候年老大比較大。線程
使用jstat查看當前Java進程JVM各區的狀況對象
使用方法blog
jstat -gcutil 進程pid 刷新秒s
舉例進程
[hadoop@localhost ~]$ jstat -gcutil 6572 1s S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673 0.00 0.13 10.61 60.38 63.44 249 117.204 2 1.468 118.673
這裏能夠看到S0、S一、E、O區各個使用率狀況,另外還有gc的次數統計
另外:
young GC:當young gen中的eden區分配滿的時候觸發
full GC:當準備要觸發一次young GC時,若是發現統計數聽說以前young GC的平均晉升大小比目前old gen剩餘的空間大,則不會觸發young GC而是轉爲觸發full GC
年輕代和年老代的 GC 關係
因爲JVM的內存有限,而Java應用程序不會管理不用的內存,因此JVM須要一種垃圾回收機制(Garbage Collection),這就是JVM GC機制。
目前常見的GC收集器的概況以下:
內存區 | GC算法 | 是否多線程 | 是否stop-the-world |
年輕代 | Serial | 單線程 | 是 |
年輕代 | ParNew | 多線程 | 是 |
年輕代 | Parallel Scavenge | 多線程 | 是 |
年老代 | CMS | 多線程 | 整個過程有2次短暫stop-the-world |
年老代 | Serial Old(MSC) | 單線程 | 是 |
年老代 | Parallel Old | 多線程 | unkown |
年輕代和年老代都有各自的垃圾回收機制。而且在咱們實際使用的時候,是相互搭配的,具體搭配關係見下圖: