深入JVM 对象优先在Eden分配

前言:对象的内存分配,大方向讲,指的是对象在堆上分配,对象的主要分配发生在新生代的Eden区,当然少数分配在老年代,分配的规则并不是固定不变的,细节取决于具体的虚拟机实现。

——对象优先在Eden区分配

大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发生一次Minor GC

虚拟机提供 -XX:PrintGCDetails这个收集器日志参数,告诉虚拟机在发生GC行为时打印内存回收日志,并且在进程退出时候输出当前运行时内存各区域的分配情况。

案例演示:

主方法中,尝试分配3个2MB大小和1个4MB大小的对象,

通过-Xms20M -Xmx20M -Xmn10M 这3个参数限制了Java堆的大小为20MB,不可拓展,其中10MB分配给新生代,剩下10MB分配给老年代。

通过-XX:SurvivorRatio=8决定新生代中Eden区与一个Survivor区间大小比为8:1

public class testAllocation {
	
	private static final int _1MB=1024*1024;
	
	/*
	 * VM启动参数
	 * 
	 * -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
	 * 
	 * 
	 * 
	 */

	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		
		byte[] allocation1,allocation2,allocation3,allocation4;
		allocation1=new byte[2*_1MB];
		
		allocation2=new byte[2*_1MB];

		allocation3=new byte[2*_1MB];

		allocation4=new byte[4*_1MB]; //将出现Minor GC


	}

}

打印的GC日志:

深入JVM 对象优先在Eden分配 

可以看到前面3个大小为2MB的对象分配在Eden区内 但最后一个4MB对象无法分配在Eden区,而选择分配在ParOldGen

也就是老年代     将对象4分配取消

//allocation4=new byte[4*_1MB]; //将出现Minor GC

结果:

深入JVM 对象优先在Eden分配 

发现Eden区空间充足,所有3个对象全在Eden区内分配 

由此可见 虚拟机在普通对象分配时,优先在新生代Eden区分配,当空间不足时会在老年代分配

 

上一篇:JVM_内存分配和回收策略


下一篇:JVM运行时内存组成分为一些线程私