今天开始实战Java虚拟机之三:“虚拟机的工作模式”。
总计有5个系列
实战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节):
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。
节选自
原文地址:http://geym2008.blog.51cto.com/9140721/1632214