【JVM】年轻代进入老年代规则

大对象直接进入老年代

然而实际在开发中,并不是所有对象都能这样进行GC流程。当对象过大时或特别大时,因为占用幸存者区空间过大或大于幸存者区,而造成反复GC,重复复制大对象增加GC时间问题,当然JVM对这方面有专门的优化。而这个机制就是大对象直接进入老年代,使用JVM参数-XX:PretenureSizeThreshold(单位为字节)设置大对象的大小,如果对象超过设置的大小会直接进入老年代,防止大对象进入年轻代造成重复GC。

  • 大对象

    大对象就是需要大量连续内存空间的对象,即数组,字符串。

注意:该参数只在Serial和ParNew收集器才会生效,即Serial与ParNew存在该参数进行大对象区分。
补充: -XX:+UseSerialGC采用Serial收集器

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

JVM采用分代收集来实现内存管理,就必须区分不同对象进入不同代中进行不同的处理,而JVM的解决方法是:给每一个对象设置对象头中的对象年龄计数器(Age)
对象流程:

  • 经历过Minor GC,能够进入Survivor(幸存者区),则设置对象年龄为1
  • 对象每经历过一次MinorGC,对象年龄就会加一
  • 当年龄增加到达一定大小(默认15,CMS收集器默认6,其他不同的收集器会有所不同),将会进入老年代。

设置进入老年代年龄阈值: -XX:MaxTenuringThreshold

对象动态年龄判断

在JVM中还有一种年龄判断机制:当一批对象的总大小大大于Survivor区域的50%,此时大于该批对象中的最大年龄的对象,直接进入老年代。

  • 当minor gc后对象总和大于Survivor区域的50%,进行
  • 该操作一般会在minor gc后进行触发
  • 可以通过JVM参数-XX:TargetSurvivorRatio进行指定

该机制是为了使多次进行GC后还存在的对象更早进入老年代,至于为什么是大于50%Survivor区的对象,实际上Eden区和Survivor区中很少存在3,4次还幸存对象
其实就是一种根据经验来将迟早会进入老年代的对象提前进入

老年代空间分配担保机制

  • 年轻代进行minor gc之前计算老年代剩余可用空间
  • 当年轻代在minor gc前所有的对象大小之和大于老年代剩余可用空间

    如果配置JVM参数-XX:-HandlePromotionFailure

    • 判断当前老年代剩余可用空间是否大于历史minor gc进入老年代的对象平均大小
    • 老年代剩余可用空间小于进入老年代对象的平均大小或未设置时,将触发Full gc
    • 老年代剩余可用空间大于进入老年代对象的平均大小时,触发minor gc,如果minor gc后存活并需要移动到老年代的对象总大小还是大于老年代的可用空间,也将会触发Full gc

      Full gc对老年代和年轻代一起回收垃圾,诺Full gc后老年代的可用空间还是无法存放minor gc后需要进入老年代的对象,将会抛出OOM错误。

  • 否则进行Full gc即可,而小于则minor gc
    在这里插入图片描述

该机制是为了尽可能的减少Full gc,并且哪怕无法避免full gc也可以在一定程度上减少年轻代对老年代的引用,加快了GC效率

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘿嘿嘿1212

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值