java内存分配与回收策略、动态对象年龄判断、空间分配担保


3.6.1 对象优先在Eden分配

对象优先在Eden分配,当Eden没有足够空间进行分配时,虚拟机发起一次Minor GC;

  1. Minor GC发生在新生代GC;
  2. Major GC/full Gc发生在老年代的GC;
        出现了Major GC,则至少伴随一次的Minor GC,除了Parallel Scavenge收集器(直接Major GC);
  3. Major GC比Minor GC快10倍以上;
  4. FULL GC清理整个堆空间;

3.6.2 大对象直接进入老年代

大对象直接进入老年代;

大对象是指需要连续空间的JAVA对象,例如很长的字符串和数组;

(了解)虚拟机提供了一个-XX:PretenureSizeThreshold参数,令大于这个设置值的对象直接在老 年代分配。
注意  PretenureSizeThreshold参数只对Serial和ParNew两款收集器有效,Parallel Scavenge收集器不 认识这个参数,Parallel Scavenge收集器一般并不需要设置


3.6.3 长期存活的对象分配到老年代

    每个对象都有一个对象年龄计数器(Age),如果新出生的对象 经过Minor GC后任然存活,并且能被surivior容纳容纳,则会被移动到 surivior中,并且设定Age=1;
对象在surivior中每熬过一次Minor GC,则Age+1;当对象的Age到一定程度,就会被移动到老年代中;

虚拟机默认对象年龄阀次数为15次,可通过-XX:MaxTenuringThreshold进行次数设置。


3.6.4 动态对象年龄判断

    虚拟机并不是永远地要求对象的年龄必须达到了MaxTenuringThreshold才能晋升到老年代,如果在Survivor空间中相同年龄的所有对象大小的 总和 大于Survivor空间的一半,年龄大于或者等于该年龄的对象直接可以进入老年代,无须等到MaxTenuringThreshold中要求的年龄。


3.6.5 空间分配担保

    开启了空间分配担保,如果老年代最大可用的连续空间小于新生代所有对象的总空间1,并且老年代最大可用连续空间大于历次晋升到老年代的对象的平均大小2,则会尝试一次有风险的Minor GC。

在发生Minor GC之前,虚拟机会检查老年代最大可用的连续空间是否大于新生代所有对象的总空间;  
    如果大于,则此次Minor GC是安全的。  
    如果小于,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果
    HandlePromotionFailure=true,那么会继续检查老年代最大可用连续空间是否大于历
    次晋升到老年代的对象的平均大小;  
        如果大于,则尝试进行一次Minor GC,但这次Minor GC依然是有风险的;
        如果小于或者HandlePromotionFailure=false,则改为进行一次Full GC

  1. 如果没有开启空间分配担保,那么应该是直接full gc. ↩︎

  2. 也是直接full gc. ↩︎

猜你喜欢

转载自blog.csdn.net/qq_43369986/article/details/109015297