《深入理解java虚拟机》--对象分配策略

对象的内存分配,主要分配在新生代的Eden区,如果启用了本地线程分配缓存(TLAB),则优先在TLAB上分配;少数情况会在老年代中分配。具体分配细节取决于当前使用哪种垃圾收集器组合,已经虚拟机中与内存相关参数的配置。

Minor GC 和 Full GC

Minor GC
指发生在新生代的垃圾回收动作,因为新生代的对象大多具备朝生夕灭的特性,所以Minor GC特别频繁,一般回收速度也比较快
Full GC:也叫Major GC
指发生在老年代的垃圾收集动作,出现了Full GC,至少出现一次Minor GC(但并非绝对,在Parallel Scavenge收集器的收集策略里就有直接进行Major GC的策略选择过程)。Major GC的速度一般比Minor GC慢10倍以上

分配策略

  • 对象优先在Eden区分配

    大多数情况下,对象在新生代的Eden区分配,如果Eden区没有足够的内存空间,虚拟机会发起一次Minor GC

  • 大对象直接进入老年代

    所谓的大对象,指的是需要大量连续内存空间的java对象,比如很长的字符串和数组,虚拟机可以设置-XX:PretenureSizeThreshold参数,令大于这个参数的对象直接在老年代分配

  • 长期存活的对象将进入老年代

    在Eden区的对象,每熬过一次Minor GC,它的年龄数就加一,当它的年龄数到达一定值时(默认15),就会晋升到老年代中,虚拟机可以通过设置-XX:MaxTenuringThreshold参数,决定年龄阈值

  • 动态年龄判断

    如果在Survivor区的相同年龄所有对象的大小之和大于Survivor空间的一半,年龄大于或等于该年龄的对象就直接进入老年代,无需等待到MaxTenuringThreshold中要求的年龄

  • 分配担保

    在发生Minor GC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有的对象空间,如果这个条件成立,那么Minor GC是确保安全的;如果不成立,虚拟机会查看HandlePromotionFailure设置值是否允许担保失败,如果允许,那么会继续检查老年代最大可利用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试进行一次Minor GC,尽管该次GC会有风险;如果小于或者HandlePromotionFailure不允许冒险,那这时需要进行一次Full GC

你可能感兴趣的:(《深入理解java虚拟机》--对象分配策略)