对象优先在新生代分配,但是有的情况对象直接在老年代分配,如下:
1、分配的对象大小大于eden space。适合所有收集器。
2、eden space剩余空间不足分配,且需要分配对象内存大小不小于eden space总空间的一半,直接分配到老年代,不触发Minor GC。适合-XX:+UseParallelGC、-XX:+UseParallelOldGC,即适合Parallel Scavenge。
3、大对象直接进入老年代,使用-XX:PretenureSizeThreshold参数控制,适合-XX:+UseSerialGC、-XX:+UseParNewGC、-XX:+UseConcMarkSweepGC,即适合Serial和ParNew收集器。
以下是测试过程:
一、第一种情况。
测试代码:
/** * 对象大小超过了eden space大小,-Xms30m -Xmx30m -Xmn10m -XX:+PrintGCDetails */ private static void testMoreThanEden() { /* Eden区为8M,from/to space各为1M */ LargeObject largeOb1 = new LargeObject(_1M * 8, "largeOb1"); }
1、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseSerialGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Heap def new generation total 9216K, used 1148K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 14% used [0x00000000fec00000, 0x00000000fed1f168, 0x00000000ff400000) from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) tenured generation total 10240K, used 8192K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) the space 10240K, 80% used [0x00000000ff600000, 0x00000000ffe00010, 0x00000000ffe00200, 0x0000000100000000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K2、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseParNewGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Heap par new generation total 9216K, used 1148K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 14% used [0x00000000fec00000, 0x00000000fed1f168, 0x00000000ff400000) from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) tenured generation total 10240K, used 8192K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) the space 10240K, 80% used [0x00000000ff600000, 0x00000000ffe00010, 0x00000000ffe00200, 0x0000000100000000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release3、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseParallelGC/-XX:+UseParallelOldGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Heap PSYoungGen total 9216K, used 1148K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) eden space 8192K, 14% used [0x00000000ff600000,0x00000000ff71f168,0x00000000ffe00000) from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) ParOldGen total 10240K, used 8192K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) object space 10240K, 80% used [0x00000000fec00000,0x00000000ff400010,0x00000000ff600000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K4、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseConcMarkSweepGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Heap par new generation total 9216K, used 1148K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 14% used [0x00000000fec00000, 0x00000000fed1f0c8, 0x00000000ff400000) from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) concurrent mark-sweep generation total 10240K, used 8192K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K
二、第二种情况,分三个测试方法代码来测试,只有第一个测试方法测试所有收集器。
测试代码:
/** * -Xms30m -Xmx30m -Xmn10m -XX:+PrintGCDetails,如果eden * space剩余空间不足分配,且需要分配的大小不小于eden space总空间的一半,直接分配到老年代,不触发Minor * GC。适合-XX:+UseParallelGC、-XX:+UseParallelOldGC。 */ private static void testMoreThanAHalfEden1() { /* eden space为8M,from/to space各为1M */ LargeObject largeOb1 = new LargeObject(_1M * 2, "largeOb1"); LargeObject largeOb2 = new LargeObject(_1M * 5, "largeOb2"); largeOb2 = null; /* 当largeOb3为1M、2M、3M都会触发Minor GC,从4M开始,直接分配到老年代 */ LargeObject largeOb3 = new LargeObject(_1M * 4, "largeOb3"); }
1、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseSerialGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Over Constructing LargeObject largeOb2 [GC (Allocation Failure) [DefNew: 8152K->554K(9216K), 0.0020207 secs] 8152K->2602K(19456K), 0.0020612 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Over Constructing LargeObject largeOb3 Heap def new generation total 9216K, used 4892K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 52% used [0x00000000fec00000, 0x00000000ff03cb68, 0x00000000ff400000) from space 1024K, 54% used [0x00000000ff500000, 0x00000000ff58a800, 0x00000000ff600000) to space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) tenured generation total 10240K, used 2048K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) the space 10240K, 20% used [0x00000000ff600000, 0x00000000ff800010, 0x00000000ff800200, 0x0000000100000000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K2、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseParNewGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Over Constructing LargeObject largeOb2 [GC (Allocation Failure) [ParNew: 8152K->564K(9216K), 0.0015776 secs] 8152K->2612K(19456K), 0.0016120 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Over Constructing LargeObject largeOb3 Heap par new generation total 9216K, used 4903K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 52% used [0x00000000fec00000, 0x00000000ff03cb68, 0x00000000ff400000) from space 1024K, 55% used [0x00000000ff500000, 0x00000000ff58d1c0, 0x00000000ff600000) to space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) tenured generation total 10240K, used 2048K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) the space 10240K, 20% used [0x00000000ff600000, 0x00000000ff800010, 0x00000000ff800200, 0x0000000100000000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release3、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseParallelGC/-XX:+UseParallelOldGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Over Constructing LargeObject largeOb2 Over Constructing LargeObject largeOb3 Heap PSYoungGen total 9216K, used 8192K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) eden space 8192K, 100% used [0x00000000ff600000,0x00000000ffe00000,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) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K4、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseConcMarkSweepGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Over Constructing LargeObject largeOb2 [GC (Allocation Failure) [ParNew: 8152K->573K(9216K), 0.0045070 secs] 8152K->2623K(19456K), 0.0046730 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] Over Constructing LargeObject largeOb3 Heap par new generation total 9216K, used 4912K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 52% used [0x00000000fec00000, 0x00000000ff03cb70, 0x00000000ff400000) from space 1024K, 55% used [0x00000000ff500000, 0x00000000ff58f550, 0x00000000ff600000) to space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) concurrent mark-sweep generation total 10240K, used 2050K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) Metaspace used 2783K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K
测试代码:
/** * -Xms30m -Xmx30m -Xmn10m -XX:+PrintGCDetails space剩余空间不足分配,且需要分配的大小不小于eden * space总空间的一半,直接分配到老年代,不触发Minor GC。适合-XX:+UseParallelGC、-XX:+UseParallelOldGC。 */ private static void testMoreThanAHalfEden2() { /* eden space为8M,from/to space各为1M */ LargeObject largeOb1 = new LargeObject(_1M * 2, "largeOb1"); LargeObject largeOb2 = new LargeObject(_1M * 2, "largeOb2"); largeOb2 = null; /* 当largeOb2为2M、3M、4M时,largeOb3直接分配到老年代 ,如果为1M时,largeOb3分配到新生代 */ LargeObject largeOb3 = new LargeObject(_1M * 4, "largeOb3"); }测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseParallelGC/-XX:+UseParallelOldGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Over Constructing LargeObject largeOb2 Over Constructing LargeObject largeOb3 Heap PSYoungGen total 9216K, used 5244K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) eden space 8192K, 64% used [0x00000000ff600000,0x00000000ffb1f188,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) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K
测试代码:
/** * -Xms40m -Xmx40m -Xmn20m -XX:+PrintGCDetails space剩余空间不足分配,且需要分配的大小不小于eden * space总空间的一半,直接分配到老年代,不触发Minor GC。适合-XX:+UseParallelGC、-XX:+UseParallelOldGC。 */ private static void testMoreThanAHalfEden3() { /* eden space为16M,from/to space各为2M */ LargeObject largeOb1 = new LargeObject(_1M * 10, "largeOb1"); /* 如果小于8M,则触发MinorGC,如果大于等于8M,直接分配到老年代 */ LargeObject largeOb2 = new LargeObject(_1M * 8, "largeOb2"); }
测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseParallelGC/-XX:+UseParallelOldGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Over Constructing LargeObject largeOb2 Heap PSYoungGen total 17920K, used 11776K [0x00000000fec00000, 0x0000000100000000, 0x0000000100000000) eden space 15360K, 76% used [0x00000000fec00000,0x00000000ff780380,0x00000000ffb00000) from space 2560K, 0% used [0x00000000ffd80000,0x00000000ffd80000,0x0000000100000000) to space 2560K, 0% used [0x00000000ffb00000,0x00000000ffb00000,0x00000000ffd80000) ParOldGen total 20480K, used 8192K [0x00000000fd800000, 0x00000000fec00000, 0x00000000fec00000) object space 20480K, 40% used [0x00000000fd800000,0x00000000fe000010,0x00000000fec00000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K
三、第三种情况。
测试代码:
/** * -XX:PretenureSizeThreshold=2097152 -Xms20m -Xmx20m -Xmn10m * -XX:+PrintGCDetails,适合-XX:+UseSerialGC、-XX:+UseParNewGC、-XX:+UseConcMarkSweepGC */ private static void testPretenureSizeThreshold() { /* eden space为16M,from/to space各为2M,如果为1M,直接分配在了新生代,如果为2M,直接分配在了老年代 */ LargeObject largeOb1 = new LargeObject(_1M * 2, "largeOb1"); }
1、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseSerialGC -XX:PretenureSizeThreshold=2097152 -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Heap def new generation total 9216K, used 1148K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 14% used [0x00000000fec00000, 0x00000000fed1f168, 0x00000000ff400000) from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) tenured generation total 10240K, used 2048K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) the space 10240K, 20% used [0x00000000ff600000, 0x00000000ff800010, 0x00000000ff800200, 0x0000000100000000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K2、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseParNewGC -XX:PretenureSizeThreshold=2097152 -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Heap par new generation total 9216K, used 1148K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 14% used [0x00000000fec00000, 0x00000000fed1f168, 0x00000000ff400000) from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) tenured generation total 10240K, used 2048K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) the space 10240K, 20% used [0x00000000ff600000, 0x00000000ff800010, 0x00000000ff800200, 0x0000000100000000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K Java HotSpot(TM) 64-Bit Server VM warning: Using the ParNew young collector with the Serial old collector is deprecated and will likely be removed in a future release3、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseParallelGC/-XX:+UseParallelOldGC -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Heap PSYoungGen total 9216K, used 3196K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) eden space 8192K, 39% used [0x00000000ff600000,0x00000000ff91f178,0x00000000ffe00000) from space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000) to space 1024K, 0% used [0x00000000ffe00000,0x00000000ffe00000,0x00000000fff00000) ParOldGen total 10240K, used 0K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) object space 10240K, 0% used [0x00000000fec00000,0x00000000fec00000,0x00000000ff600000) Metaspace used 2784K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K4、测试环境:Java HotSpot(TM) 64-Bit Server VM
-XX:+UseConcMarkSweepGC -XX:PretenureSizeThreshold=2097152 -Xms20m -Xmx20m -Xmn10m -XX:+PrintGCDetails
测试结果:
Over Constructing LargeObject largeOb1 Heap par new generation total 9216K, used 1148K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000) eden space 8192K, 14% used [0x00000000fec00000, 0x00000000fed1f0c8, 0x00000000ff400000) from space 1024K, 0% used [0x00000000ff400000, 0x00000000ff400000, 0x00000000ff500000) to space 1024K, 0% used [0x00000000ff500000, 0x00000000ff500000, 0x00000000ff600000) concurrent mark-sweep generation total 10240K, used 2048K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000) Metaspace used 2786K, capacity 4486K, committed 4864K, reserved 1056768K class space used 300K, capacity 386K, committed 512K, reserved 1048576K