【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有分配了32M的空间,一共是是6M的空间,而我们的Eden空间只有8192的大小,容纳不下了,但是allocation1,2,3都是存活的,回收不了,那么这里我们的虚拟机的动作是吧新的4M分配到老年代中!!!!,这样我们的老年代的空间就被占用了4M(这个是虚拟机的策略)

 

但是如果我们想要把原来的6M放到老年代,吧新的4M放到新生代,(这样才比较符合我们的思维),那么我们可以要求在分配4M之前进行一次GC,吧我们原来的6M的年龄+1,这样我们的原来的6M就会被移动到老年代,我们的新的4M空间就会存在新生代中。

 

 

posted @ 2016-03-31 09:31  cutter_point  阅读(294)  评论(0)    收藏  举报