- JVM配置参数 : 堆内存设置为20M; 年轻代10M; Edon:Survivor from:Survivor to = 8:1:1 即 8M:1M:1M
-Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
- Java环境
jdk1.8.0_202
- 程序代码
public class MinorGCDemo {
private static final int _1M = 1024 * 1024;
public static void main(String[] args){
byte[] arr1, arr2, arr3, arr4;
arr1 = new byte[2 * _1M]; // 分配到 Edon
arr2 = new byte[2 * _1M]; // 分配到 Edon
arr3 = new byte[2 * _1M]; // 分配到 Edon
/*
Edon 只剩2M了,空间不足,引发 Minor GC;
Minor GC时(Edon--》Survivor时),发现Survivor可用空间只有1M,3个2M的对象无法回收;
因此这三个对象会放到老年代(老年代占用6M);
Edon空出来,分配arr4,此时Edon占用空间4M;
*/
arr4 = new byte[4 * _1M];
}
}
[GC (Allocation Failure) [PSYoungGen: 7535K->999K(9216K)] 7535K->3842K(19456K), 0.0021218 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
PSYoungGen total 9216K, used 5419K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 53% used [0x00000000ff600000,0x00000000ffa511a0,0x00000000ffe00000)
from space 1024K, 97% used [0x00000000ffe00000,0x00000000ffef9c28,0x00000000fff00000)
to space 1024K, 0% used [0x00000000fff00000,0x00000000fff00000,0x0000000100000000)
ParOldGen total 10240K, used 6939K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
object space 10240K, 67% used [0x00000000fec00000,0x00000000ff2c6c20,0x00000000ff600000)
Metaspace used 3202K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 345K, capacity 388K, committed 512K, reserved 1048576K
-
[GC (Allocation Failure) [PSYoungGen: 7535K->999K(9216K)] 7535K->3842K(19456K), 0.0021218 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
- 在
arr4 = new byte[4 * _1M];
分配空间失败,则发生minor gc;
- 在
-
ParOldGen total 10240K, used 6939K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
- Edon已经占用了6M,空间不足以分配,Survivor可用也只有1M,所以arr1、arr2、arr3 被通过分配担保机制分配到老年代中
-
eden space 8192K, 53% used [0x00000000ff600000,0x00000000ffa511a0,0x00000000ffe00000)
- Edon空出来,分配4M空间给arr4
所以运行完 arr4 = new byte[4 * _1M];
这行代码时:
堆空间内存:
Edon: 总空间8M 占用4M 存放arr4
老年代: 总空间10M 占用6M 存放arr1、arr2、arr3
- JVM配置参数 : 堆内存设置为20M; 年轻代10M; Edon:Survivor from:Survivor to = 8:1:1 即 8M:1M:1M
- -XX:PretenureSizeThreshold=3145728 : 单位字节,大于这个值的对象直接分配到老年代
-Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
- Java环境
jdk1.8.0_202
- 程序代码
/**
-Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:PretenureSizeThreshold=3145728
*/
public class PretenureSizeThresholdDemo {
private static final int _1M = 1024 * 1024;
public static void main(String[] args){
byte[] arr = new byte[_1M];
}
}
Heap
PSYoungGen total 9216K, used 5651K [0x00000000ff600000, 0x0000000100000000, 0x0000000100000000)
eden space 8192K, 68% used [0x00000000ff600000,0x00000000ffb84f20,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 3254K, capacity 4496K, committed 4864K, reserved 1056768K
class space used 347K, capacity 388K, committed 512K, reserved 1048576K
我们没有看到GC,但是老年代已经占用了4M空间:
ParOldGen total 10240K, used 4096K [0x00000000fec00000, 0x00000000ff600000, 0x00000000ff600000)
- 这就是指定了的
-XX:PretenureSizeThreshold=3145728
大于这个值的对象直接分配到了老年代
- 这就是指定了的
JVM给每一个对象定义了一个对象年龄计数器
。
如果对象在Edon出生并且经过第一次Minor GC后仍然存活,并且能够被Survivor容纳,将被移动到Survivor空间中,将对象年龄设置为1.