关于JDK6和JDK7的GC
miroku
2013-08-29
/** * VM参数:-Xms20M -Xmx20M -Xmn10M -XX:SurvivorRatio=8 -XX:+PrintGCDetails */ public class MinorGC { private static final int _1MB = 1024 * 1024; public static void testAllocation() { byte[] allocation1, allocation2, allocation3, allocation4; allocation1 = new byte[2 * _1MB]; allocation2 = new byte[2 * _1MB]; allocation3 = new byte[2 * _1MB]; allocation4 = new byte[4 * _1MB]; // 出现一次Minor GC } public static void main(String[] args) { testAllocation(); } } 以上代码在执行的时候,在JDK7和JDK6上有不同的表现。我测试了JDK6 32位client模式,JDK7 64位client模式 JDK764位server模式,在JDK7-64位(无论client还是server)下GC日志如下: Heap PSYoungGen total 9216K, used 6980K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) eden space 8192K, 85% used [0x00000000ff600000,0x00000000ffcd1048,0x00000000ffe00000) from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) ParOldGen total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) object space 10240K, 40% used [0x00000000fec00000,0x00000000ff000010,0x00000000ff600000) PSPermGen total 21248K, used 2526K [0x00000000f9a00000, 0x00000000faec0000, 0x00000000fec00000) object space 21248K, 11% used [0x00000000f9a00000,0x00000000f9c779e8,0x00000000faec0000) 而在JDK6 32位client下,会进行一次Minor GC。据有的同学测试在JDK6-64位上表现和JDK7-64位是一样的。所以想问下:是不是JDK6和JDK7的GC策略有变化,使得在JDK7时,不进行Minor GC,而直接把4M的数组在老年代分配了? |
|
RednaxelaFX
2013-08-29
miroku 写道 所以想问下:是不是JDK6和JDK7的GC策略有变化,使得在JDK7时,不进行Minor GC,而直接把4M的数组在老年代分配了?
不是。 您用的所谓JDK7 64位Client VM,多半实际上是Server VM来的。Oracle JDK并没有发布64位的Client VM,而只有Server VM。 您试试在所谓JDK7 64位Client VM上执行这个: java -client -version 然后把结果贴出来看看~ 实际上您看到的区别就是Client VM跟Server VM默认用的GC堆不同带来的。 Client VM默认用Serial GC,Server VM默认用Parallel GC。后者有直接把大对象分配在old gen的逻辑,而前者没启动同类逻辑。仅此而已。 另外请参考之前一帖的分析方法:http://hllvm.group.iteye.com/group/topic/38293 |
|
miroku
2013-08-29
果然如此,多谢大神
java -client -version java version "1.7.0_17" Java(TM) SE Runtime Environment (build 1.7.0_17-b02) Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode) |
|
yasenagat
2013-09-02
RednaxelaFX 写道 miroku 写道 所以想问下:是不是JDK6和JDK7的GC策略有变化,使得在JDK7时,不进行Minor GC,而直接把4M的数组在老年代分配了?
不是。 您用的所谓JDK7 64位Client VM,多半实际上是Server VM来的。Oracle JDK并没有发布64位的Client VM,而只有Server VM。 您试试在所谓JDK7 64位Client VM上执行这个: java -client -version 然后把结果贴出来看看~ 实际上您看到的区别就是Client VM跟Server VM默认用的GC堆不同带来的。 Client VM默认用Serial GC,Server VM默认用Parallel GC。后者有直接把大对象分配在old gen的逻辑,而前者没启动同类逻辑。仅此而已。 另外请参考之前一帖的分析方法:http://hllvm.group.iteye.com/group/topic/38293 试了一下,发现 Serial GC设置了-XX:PretenureSizeThreshold=3145728后,只要对象超过这个大小, 不管eden是否还有足够大的剩余,都把超过3M的对象放到old Paralle,设置次参数应该无效,当eden空间不足时,才会把大对象直接放到old,不进行minor gc |