- 对象优先分配在Eden 代
对象在新生代Eden区分配,当Eden 区没有足够的空间进行分配时,虚拟机将会发起一次Minor GC
- 大对象直接进入老年代
大对象:需要连续内存空间的Java对象。大对象直接在老年代分配是为了避免在Eden 区 以及两个 Survivor 区之间发生大量的内存复制(新生代回收算法采用 复制算法)
- 长期存活的对象将进入老年代
判定长期存活的对象:虚拟机给每个对象定义一个对象年龄计数器,如果对象在Eden代出生并经过第一次Minor GC 后依然存活,并且能够被survivor容纳的话,将被移动到 survivor空间中,并且对象年龄设为1,对象在survivor区中每熬过一次Minor GC,年龄就增加了1岁,当它的年龄增加到一定程度(默认为 15 岁),就将会被晋升到老年代中
- 动态对象年龄判定
虚拟机并不是永远的要求对象的年龄必须达到年龄才能晋升老年代,如果在survivor区相同年龄所有对象大小的总和大于survivor空间一半,年龄大于等于该年龄的对象直接进入老年代
- 空间分配担保
在Minor GC前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象总空间,确保Minor GC 是安全的。否则虚拟机会查看是否允许担保失败;如果允许,继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行Minor GC;如果小于,或者不允许冒险,要进行 一次Full GC
- 问题1:Minor GC 和 Full GC 的区别
Minor GC:又称新生代GC,发生在新生代的垃圾收集动作,Java对象大多数都是昭生夕灭,Minor GC 非常频繁,回收速度也快
Major GC/Full GC:又称老年代GC,发生在老年代的GC,出现了Major GC,经常伴随至少一次Minor GC,Major GC的速度一般比Minor GC慢10倍以上 - 问题二:空间分配担保中的冒险是指什么
新生代使用复制收集算法,但是为了内存利用率,只使用一个survivor空间来轮换备份,因此当出现大量对象在Minor GC 后依然存活的情况们就需要老年代进行分配担保,把survivor无法容纳的对象直接进入老年代。进行担保,前提是老年代知道本身的剩余空间,有多少对象会活下来是不知道的,取之前每次回收晋升到老年代对象的平均大小作为经验值,与剩余空间作比较,看是都进行Full GC 来腾出更多空间