今天開始實戰Java虛擬機之三:“G1的新生代GC”。
總計有5個系列
- 實戰Java虛擬機之一“堆溢出處理”
- 實戰Java虛擬機之二“虛擬機的工作模式”
- 實戰Java虛擬機之三“G1的新生代GC”
- 實戰Java虛擬機之四“禁用System.gc()”
- 實戰Java虛擬機之五“開啟JIT編譯”
新生代GC的主要工作是回收eden區和survivor區。一旦eden區被占滿,新生代GC就會啟動。新生代GC收集前后的堆數據如圖5.6所示,其中E表示eden區,S表示survivor區,O表示老年代。可以看到,新生代GC只處理eden和survivor區,回收后,所有的eden區都應該被清空,而survivor區會被收集一部分數據,但是應該至少仍然存在一個survivor區,類比其他的新生代收集器,這一點似乎並沒有太大變化。另一個重要的變化是老年代的區域增多,因為部分survivor區或者eden區的對象可能會晉升到老年代。

圖5.6 G1的新生代GC
新生代GC發生后,如果打開了PrintGCDetails選項,就可以得到類似以下的GC日志(這里只給出了部分日志,完全的日志及其分析請看《實戰Java虛擬機》一書第5.4.6節):
0.336: [GC pause (young), 0.0063051 secs] …. [Eden: 235.0M(235.0M)->0.0B(229.0M) Survivors: 5120.0K->11.0M Heap: 239.2M(400.0M)->10.5M(400.0M)] [Times: user=0.06 sys=0.00, real=0.01 secs]
和其他回收器的日志相比,G1的日志內容非常豐富。當然我們最為關心的依然是GC的停頓時間以及回收情況。從日志中可以看到,eden區原本占用235M空間,回收后被清空,survivor區從5M增長到了11M,這是因為部分對象從eden區復制到survivor區,整個堆合計為400M,從回收前的239M下降到10.5M。
節選自

《實戰Java虛擬機》一書Q交流群:397196583
