jvm打破砂锅问到底- JVM中对象进入老年代的条件

深入理解Java虚拟机书中有详尽描述, 本文做一下咀嚼.
3.8.1 对象优先在Eden分配
3.8.2 大对象直接进入老年代 (默认是0)
-XX:PretenureSizeThreshold:晋升老年代对象大小,超过指定大小直接在老年代分配,默认为0
原因:

  1. 大对象会过度挤压可用内存, 导致提前触发垃圾回收. 所以大对象没有挤占新生代, 如果是没有专门的大对象区的话, 就只能放在老年代了
  2. 新生代是标记复制算法, 大对象需要更高的复制成本.
    这里的大指的是占用内存, 而不是序列化后的大小. 所以一般要复现这个情况得建立数组比如new byte[4 * _1MB]. (成员变量如果是引用类型才占8字节, 如果小于32G指针压缩为4字节, 根据大对象默认是1m判定, 得250个成员变量引用类型, 一般那有这么多, 除非成员变量有数组, 比如有些大数量的arraylist场景, 比方说解析excel或者或者批处理, 处理文件等) 如果设置了PretenureSizeThreshold 所以使用者确定这个大对象应该是需要打老年代的, 就可以直接大对象, 如果使用者认为是朝生夕死的, 就不要触碰到这个大对象的阈值
    3.8.3 长期存活的对象将进入老年代
    老的量化定义, 超过15岁. 对象头里只有4位, 所以可以改为0-15, 默认15
    3.8.4 动态对象年龄判定
    gc后期, 如果遇到年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时就会把年龄n(含)以上的对象都放入老年代。源自jDK1.8源码逻辑
    提前进入, 意味着留出更多可用空间, 延缓ygc触发垃圾回收.
    原因:
    个人理解是为了减少空转, 也就是这种情况下更多的可能性是意味着, 这些大龄对象不会突然死亡. 因为占比已经到了50%, 空转的可能性更大. 比如上文说3.8.2的时候, 如果有复杂引用关系, 那就有一堆的小对象, 大家是紧紧相随的, 如果出现空转, 就是类似于一个大对象在空转.
    15毕竟是静态配置, 万一比较大就比较尴尬, 提前晋升每次晋升一点点, 相比于被动担保, 压力提前分担了一点

3.8.5 空间分配担保
gc后期把Survivor无法容纳的对象直接送入老年代,这与生活中贷款担保类似。老年代要进行这样的担保, JDK 6 Update 24之
后的规则变为只要老年代的连续空间大于新生代对象总大小或者历次晋升的平均大小,就会进行
Minor GC,否则将进行Full GC。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值