JVM Young GC模擬觸發和日誌檢視

先上模擬程式碼

模擬程式碼

JVM Young GC模擬觸發和日誌檢視

JVM引數設定

我本地JDK是1。8,引數是按照1。8來設定的

JVM Young GC模擬觸發和日誌檢視

引數解讀:

-XX:NewSize=5120k 初始新生代(年輕代)大小5M

-XX:MaxNewSize=5120k 最大新生代(年輕代)大小5M

-XX:InitialHeapSize=10240k 初始堆大小10M

-XX:MaxHeapSize=10240k 最大堆大小10M

-XX:SurvivorRatio=8 年輕代eden區和兩個survivor區比例是8:1:1

-XX:PretenureSizeThreshold=10240k 當物件大於10M時直接進入老年代

-XX:+UseParNewGC (年輕代)使用parnew垃圾回收器

-XX:+UseConcMarkSweepGC (老年代)使用cms垃圾回收器

-XX:+PrintGCDetails 列印gc詳細日誌

我用的idea,給執行程式配置上面的jvm引數如下

JVM Young GC模擬觸發和日誌檢視

執行GcTest的main方法後,在控制檯列印瞭如下資訊

JVM Young GC模擬觸發和日誌檢視

可以設定jvm引數-Xloggc:gc。log把gc日誌輸出到一個名叫gc。log檔案裡去

增加jvm引數後如下

JVM Young GC模擬觸發和日誌檢視

我們重新執行main方法,會看到已經生成了一個gc。log檔案了

JVM Young GC模擬觸發和日誌檢視

Young GC日誌解讀

JVM Young GC模擬觸發和日誌檢視

CommandLine flags 此次執行程式採取的JVM引數

告訴我們此次執行程式採取的JVM引數是什麼,就是上面我們自己設定的,只不過我們的單位是k,它這裡是位元組,你除以1024就會發現跟我們設定的一樣;以及一些預設的JVM引數。

一次GC的概要說明

0。207: [GC (Allocation Failure) 0。207: [ParNew: 3938K->512K(4608K), 0。0015174 secs] 3938K->1768K(9728K), 0。0016622 secs] [Times: user=0。00 sys=0。00, real=0。00 secs]

[GC (Allocation Failure) 0。207表示系統執行0。207秒就會發生本地GC,發生本次GC的原因是Allocation Failure 分配失敗

這裡為了方便理解,畫圖如下

JVM Young GC模擬觸發和日誌檢視

要分配byte2這個區域性變數對應的1M陣列時,發現Eden區不夠用了(有人會說Eden區有4M,剛好能用呀,其實為了儲存這個1M陣列,JVM還會附帶一些資訊,陣列真實大小是大於1M的,還有一些看不到的物件,後面分析堆的gc日誌就會看到),就會Allocation Failure,此時就會觸發一次Young GC。

ParNew: 3938K->512K(4608K), 0。0015174 secs :表示年輕代gc耗時0。0015174 秒,gc回收後總記憶體佔用從3939k變成512k,4608k是年輕代總大小

3938K->1768K(9728K), 0。0016622 secs:這句是針對整個Java堆的

Times: user=0。00 sys=0。00, real=0。00 secs 這句單位是秒,代表整個gc幾乎是不耗時的,就幾毫秒

gc後堆記憶體使用情況

就是上面gc。log裡heap這一段

JVM Young GC模擬觸發和日誌檢視

par new generation total 4608K, used 3701K :表示ParNew垃圾收集器負責的年輕代共4608K(4。5M,因為有一個survivor to 0。5M是空置的),已經用了3701k

eden space 4096K, 77% used :表示eden區共4096k(4M)已經使用77%

from space 512K, 100% used :表示survivor from區512k,已使用100%

to space 512K, 0% used : 表示survivor to 區512k,已使用0%