大对象直接进入老年代。 虚拟机提供了一个阈值参数,令大于这个设置值的对象直接在老年代中分配。如果大对象进入新生代,新生代采用的复制算法收集内存,会导致在Eden区和两个Survivor区之间发生大量的内存复制,应该避免这种情况。
长期存活的对象进入老年代。 虚拟机给每个对象定义了一个年龄计数器,对象在Eden区出生,经过一次Minor GC后仍然存活,并且能被Survivor区容纳的话,将被移动到Survivor区中,此时对象年龄设为1。然后对象在Survivor区中每熬过一次 Minor GC,年龄就增加1,当年龄超过设定的阈值时,就会被移动到老年代中。
动态对象年龄判定: 如果在 Survivor 空间中所有相同年龄的对象,大小总和大于 Survivor 空间的一半,那么年龄大于或等于该年龄的对象就直接进入老年代,无须等到阈值中要求的年龄。
空间分配担保: 如果老年代中最大可用的连续空间大于新生代所有对象的总空间,那么 Minor GC 是安全的。如果老年代中最大可用的连续空间大于历代晋升到老年代的对象的平均大小,就进行一次有风险的 Minor GC,如果小于平均值,就进行 Full GC 来让老年代腾出更多的空间。因为新生代使用的是复制算法,为了内存利用率,只使用其中一个 Survivor 空间来做轮换备份,因此如果大量对象在 Minor GC 后仍然存活,导致 Survivor 空间不够用,就会通过分配担保机制,将多出来的对象提前转到老年代,但老年代要进行担保的前提是自己本身还有容纳这些对象的剩余空间,由于无法提前知道会有多少对象存活下来,所以取之前每次晋升到老年代的对象的平均大小作为经验值,与老年代的剩余空间做比较。
网友评论