理解JVM GC


理解JVM GC對於我們把控Java應用有很大的幫助。下面我從運維角度,把網上的JVM相關的資料整理如下,以加深對JVM GC的理解。
如有錯誤的地方,請看官指正。

JVM內存使用分類

JVM的內存分區關系:

  • 【JVM整個堆內存】=年輕代+年老代
  • 【JVM整個內存】= (堆內存) + 非堆內存 = (年輕代 + 年老代) + 持久代

關於年輕代、年老代、持久代

對於JVM來說,內存分為三個區域:年輕代、年老代和持久代。年輕代和年老代用來存放Java進程中的變量,持久代用於放Java類信息。
一般對我們主要關注年輕代和年老代。JVM的分代可以用下面這張圖表示:
jvm分代

年輕代分為三個區域:一個Eden區(簡稱E區域),兩個Survivor區(我們定義為S0、S1)。
Java程序新申請的變量會放在E區;當E區滿時,所有存活的對象會被移動到S0區。當S0區滿時,S0中存活的對象被移動到S1區(這時候S0就空了,E區滿時存活的對象會移動到S1區)。當S1區滿時,將經歷過S0的對象移動到年老代(O區)。S0區和S1區是對等的,這樣一個對象要進入持久代會經歷E區、S0區、S1區,然后進入到O區。

年老代用於存放從年輕代晉升上來的對象(E區->S0區->S1區->O區),一般我們設置的時候年老大比較大。

使用jstat查看當前Java進程JVM各區的情況

使用方法

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、S1、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

年輕代和年老代都有各自的垃圾回收機制。並且在我們實際使用的時候,是相互搭配的,具體搭配關系見下圖:
jvm_gc


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM