今天开始实战Java虚拟机之三:“虚拟机的工作模式”。

总计有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区的对象可能会晋升到老年代。

实战Java虚拟机之三“G1的新生代GC”_第1张图片

图5.6  G1的新生代GC

新生代GC发生后,如果打开了PrintGCDetails选项,就可以得到类似以下的GC日志(这里只给出了部分日志,完全的日志及其分析请看《实战Java虚拟机》一书第5.4.6节):

1
2
3
4
5
6
7
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虚拟机之一“堆溢出处理”

实战Java虚拟机之二“虚拟机的工作模式”

节选自

25612fm立体图