堆内存模型:

java 年轻代 gc不了 jvm默认年轻代比例_老年代

 

年轻代: 

根据分代算法,默认小于15岁的对象称作年轻代,年轻代分为Eden区、幸存者区(Survivor Form,Survivor To),三者比例为:8:1:1

Eden 分区:对象出生分区,新对象存放区域

幸存者分区:经过一次MinorGC后依然存活的对象会移动到此。

老年代:

根据分代算法默认大于15岁的对象称作老年代对象,JVM会将年轻代对象移动至老年代。

永久代:

永久保存数据区域。主要保存Class等元数据信息,JDK1.8开始移除永久代用Metadata元数据区来存放,将永久代从堆中直接放置到直接内存中。原因本人觉得,是由于目前以Spring为主流的的动态代理、反射的大量使用,导致永久代的空间需求和用途已经发生非常大的改变,移除到直接内存中,可以简化JVM垃圾回收,内存管理的工作,也扩展了永久代的占用空间,操作使用更加的便捷。

jvm堆模型默认配置参数:

★ Eden:From:To - > 8:1:1

★ 年轻代:老年代 - > 1 : 2


分代算法:

JVM为每个对象建立一个年龄计数器,每执行一次MinorGC仍然存活的对象,则计数器加1,位于Eden分区的对象,会被移动到幸存者分区(Survivor),默认满15岁会被晋升为老年代。

分配策略

1.对象优先在Eden分配

新建对象一般会存放于Eden分区。如果Eden分区空间不足,则执行MinorGC,进行垃圾回收,如果依然无法存放,将放置到Survivor分区,如果Survivor分区依然空间不足,则会将Survivor分区的对象通过分配担保机制提前转移到老年代。

2.大对象直接进入老年代

新建对象需要大量连续内存空间,超过  JVM指定阀值(-XX:PretenureSizeThreshold)时,对象将直接在老年代中分配。

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

内存中对象的年龄超过JVM通过指定阀值(-XX:MaxTenuringThreshold=15)后,将直接进入老年代

4.动态对象年龄判定

Survivor分区中,相同年龄所有对象大小的总和大于Survivor分区大小的一般是,自动进入老年代。

5.空间分配担保

如果多次MinorGC后,Survivor分区依然没有空间存放对象,则在老年代空间足够的情况下直接转为老年代。

  • 如果数据大小大于老年代数据空间,则担保分配失败
  • 如果数据大小大于晋升为老年代的数据平均大小,则担保分配失败。
  • 如果数据大小大于参数HandlePromotionFailure,则担保分配失败