大多数状况下,对象在新生代 Eden 区中分配。当 Eden 区没有足够空间进行分配时,虚拟机将发起一次 Minor GC。安全
大对象是指须要大量连续内存空间的 Java 对象,如很长的字符串或数据。对象
一个大对象可以存入 Eden 区的几率比较小,发生分配担保的几率比较大,而分配担保须要涉及大量的复制,就会形成效率低下。内存
虚拟机提供了一个 -XX:PretenureSizeThreshold 参数,令大于这个设置值的对象直接在老年代分配,这样作的目的是避免在 Eden 区及两个 Survivor 区之间发生大量的内存复制。字符串
JVM 给每一个对象定义了一个对象年龄计数器。当新生代发生一次 Minor GC 后,存活下来的对象年龄 +1,当年龄超过必定值时,就将超过该值的全部对象转移到老年代中去。虚拟机
使用 -XXMaxTenuringThreshold 设置新生代的最大年龄,只要超过该参数的新生代对象都会被转移到老年代中去。io
若是当前新生代的 Survivor 中,相同年龄全部对象大小的总和大于 Survivor 空间的一半,年龄 >= 该年龄的对象就能够直接进入老年代,无须等到 MaxTenuringThreshold 中要求的年龄。效率
JDK 6 Update 24 以前的规则是这样的:
在发生 Minor GC 以前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代全部对象总空间,
若是这个条件成立,Minor GC 能够确保是安全的;
若是不成立,则虚拟机会查看 HandlePromotionFailure 值是否设置为容许担保失败,
若是是,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,
若是大于,将尝试进行一次 Minor GC,尽管此次 Minor GC 是有风险的;
若是小于,或者 HandlePromotionFailure 设置不容许冒险,那此时也要改成进行一次 Full GC。date
JDK 6 Update 24 以后的规则变为:
只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会进行 Minor GC,不然将进行 Full GC。数据
经过清除老年代中废弃数据来扩大老年代空闲空间,以便给新生代做担保。内存分配
这个过程就是分配担保。