【JVM】1、关于对象在JVM中优先分配区域
1 package ch03; 2 3 public class TestGC1 4 { 5 private static final int _1MB = 1024 * 1024; 6 7 /** 8 * 测试JVM内存的分配,新生代和老年代的分区 9 * 参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 10 * 输出gc日志, 堆内存初始化大小20M,堆内存最大20M,年轻代大小10M, 输出GC的详细日志,Eden的区域是一个survivor区域的8倍 11 */ 12 public static void testAllocation() 13 { 14 byte[] allocation1, allocation2, allocation3, allocation4; 15 16 allocation1 = new byte[2 * _1MB]; //申请两兆 17 allocation2 = new byte[2 * _1MB]; 18 allocation3 = new byte[2 * _1MB]; 19 //这里我们再eden已经申请了6M的空间,而实际上新生代大小是EDEN + 一个survivor Eden=8M survivor两块分别1M(因为复制算法的原因) 20 allocation4 = new byte[4 * _1MB]; 21 } 22 23 public static void main(String[] args) 24 { 25 testAllocation(); 26 27 } 28 29 }
运行结果:

这里是采用了Parallel Scavenge收集器,从内存中收集信息,可以看到我们的新生代大小是10M,我们堆内存一共是20M,那么老年代的大小也是10M
从GC日志中我们可以看出,我们的老年代中使用了4M的空间,为什么?
因为我们前面allocation有分配了3个2M的空间,一共是是6M的空间,而我们的Eden空间只有8192的大小,容纳不下了,但是allocation1,2,3都是存活的,回收不了,那么这里我们的虚拟机的动作是吧新的4M分配到老年代中!!!!,这样我们的老年代的空间就被占用了4M(这个是虚拟机的策略)
但是如果我们想要把原来的6M放到老年代,吧新的4M放到新生代,(这样才比较符合我们的思维),那么我们可以要求在分配4M之前进行一次GC,吧我们原来的6M的年龄+1,这样我们的原来的6M就会被移动到老年代,我们的新的4M空间就会存在新生代中。


浙公网安备 33010602011771号