对象优先分配在Eden
对于大多数情况来说,新生代优先在Eden区中分配,当Eden中内存不够时,会触发 MinorGC.
举个例子,当Eden区为8M,两个Survivor区,各1M(Hotspot虚拟机),那么新生代总的可用空间就是9M。
某个时刻,新生代已用内存6M(3个2M的对象),此时,新创建一个4M的对象,发现新生代可用内存不足,此时触发MinorGC,在GC期间,已存在的三个对象不能完全放入Survivor区中,则会通过 分配担保机制,将这三个对象提前转移到老年代中。
最后的结果是:Eden区占用4M,Survivor区空闲,老年代占用6M。
大对象直接进入老年代
大对象——需要大量连续空间的Java对象。(代表:很长的数组和字符串)
虚拟机提供了-XX:PretenureSizeThreshold来设置大于该值的直接进入老年代。
长期存活的对象进入老年代
首先,虚拟机采用分代收集的思想管理内存。每个对象都有一个Age计数器(存在于对象头)。
如果新生代出生在Eden,那么当它经历第一次MinorGC后,年龄计数器置为1,并进入Survivor区(此时采用复制算法)。每次经历GC,都会将年龄加一,默认在年龄大于等于15时,进入老年代。
动态年龄判定
所谓动态,肯定是相较于上面,其思想是这样的:即使对象的年龄并没有达到15(当然这个参数可以设定),如果存在一个年龄分界点,年龄大于等于该分界点的对象所占内存大于或等于新生代总内存的一半时,这些对象将直接进入老年代。
空间分配担保
这一概念,针对新生代来说。其实意思就是,新生代主要采用复制算法进行回收内存,当剩余内存不足以承担所有存活的对象时(就是上面所举的例子),怎么办?此时需要一块区域来进行“担保”。这就是老年代。
而老年代一般采用标记算法,无需额外担保空间。