对象优先在新生代分配,但是有的情况对象直接在老年代分配,如下:
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、测试环境:JDK1.8.0_144,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 1048576K
2、测试环境:JDK1.8.0_144,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 release
3、测试环境:JDK1.8.0_144,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 1048576K
4、测试环境:JDK1.8.0_144,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、测试环境:JDK1.8.0_144,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 1048576K
2、测试环境:JDK1.8.0_144,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 release
3、测试环境:JDK1.8.0_144,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 1048576K
4、测试环境:JDK1.8.0_144,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");
}
测试环境:JDK1.8.0_144,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");
}
测试环境:JDK1.8.0_144,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、测试环境:JDK1.8.0_144,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 1048576K
2、测试环境:JDK1.8.0_144,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 release
3、测试环境:JDK1.8.0_144,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 1048576K
4、测试环境:JDK1.8.0_144,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
附,大对象代码:
static class LargeObject {
private byte[] data;
private String name;
public LargeObject(int size, String name) {
data = new byte[size];
this.name = name;
System.out.println("Over Constructing LargeObject " + name + System.lineSeparator());
}
public String getName() {
return name;
}
}