JVM-动态年龄判断你真的理解了吗

什么对象才能直接进入老年代?

你可能很快就说出来,毕竟八股文不是白背的。

大对象直接进入老年代。

动态年龄判断

年龄大于阈值,进入老年代
Minor GC后,存活的对象空间大于survivor空间,直接进入老年代。

好了嘛,应该没了吧。

这次,我们把目光聚焦到:动态年龄判断。
下面这图片,摘自JVM书的一段话:

什么时候对象能进入老年代空间时?
其中一个触发条件就是:动态年龄判断。

简单点说:在survivor中,相同年龄的所有对象大小大于survivor的一般空间。年龄大于或等于该年龄的对象可以进入老年代。

但真的是这样子吗?

前提条件:现在我假设survivor空间有100M空间。
来。我举个例子哈,跟着我的思路走一遍。

假设年龄3的对象大小超过了survivor区域的一半,比如占据60M吧。
我们分析一下:年龄为3,说明经历了3次GC都存活了下来。
然后我们思考一下,年龄3的对象是从哪里来的?
肯定是从年龄2的对象中来的。这点毋庸置疑吧!

我们再换个思路想一下。

既然,年龄3的对象是从年龄2的对象中来的。(先说明哈:年龄,只增不减)
现在年龄3的对象都已经超过survivor区域的一半了。

  • 那是不是可以说明:年龄2的对象也肯定超过survivor区域的一半。

同理可得:年龄2的对象是从年龄1的对象中来的,那么年龄1的对象也肯定超过一半,是吧。这毋庸置疑吧!
我们来复习一下:

在survivor中,相同年龄的所有对象大小大于survivor的一般空间。年龄大于或等于该年龄的对象可以进入老年代。

你看,如果真的是如上面所说的规则。超过一半空间,该年龄或大于该年龄的对象,都进入老年代。

那还有年龄3的对象什么事呢?

因为年龄3的对象,是从年龄2对象来的,而年龄2对象是从年龄1中的对象来的。
进入老年代的应该在年龄1的对象。压根不会不发展到年龄3的对象。
但真的是这样子吗?
肯定不是,让超过survivor区域一般的年龄1的对象直接进入老年代。JVM的设计者疯了吗?

还是书本的描述有错呢?

真实情况是这样子的:

年龄1+年龄2+年龄3+年龄N的对象加起来的空间,大于survivor区域的一半,就会让年龄N和年龄N以上的对象进入老年代。动态年龄判断应该是这样子的。说的通俗一点:就是年龄从小到大对象的占据空间的累加和,而不是某一个特定年龄对象占据的空间。

有没有被书本骗了的感觉。。。。

好嘛,如果你还不信。

Talk is cheap,Show me the money

搞错了,重来

Talk is cheap ,Show me the code。

uint ageTable::compute_tenuring_threshold(size_t survivor_capacity) {
	//survivor_capacity是survivor空间的大小
  //desired_survivor_size就是动态年龄判断是否对象进入老年代的阈值
  //TargetSurvivorRatio:默认50
  size_t desired_survivor_size = (size_t)((((double) survivor_capacity)*TargetSurvivorRatio)/100);
  size_t total = 0;
  uint age = 1;
  while (age < table_size) {
  //sizes数组是每个年龄段对象大小
  //total就是年龄从小到大的对象占据的空间累加和
    total += sizes[age];
  //如果累加和大于阈值,就直接跳出循环,假设磁盘的age等于3吧
    if (total > desired_survivor_size) break;
    age++;
  }
  //MaxTenuringThreshold上限是15,现在age是3,那么result就是等于3
  uint result = age < MaxTenuringThreshold ? age : MaxTenuringThreshold;
	...
}

上面这段代码,也证实了我的猜想:

真正的动态年龄判断:是年龄从小到大的对象占据的空间,大于survivor区域的一半,然后把等于或大于该年龄的对象,放入到老年代。

小结

这就是书本理理论和实践的差距吧。你不真正看一下源码,可能一直都以为书本说的是真的。这也从侧面说明了:源码无秘密。
补充知识

大对象直接进入老年代。

那多大的对象是大对象?大于下面参数的对象,就是大对象
直接通过:-XX:PretenureSizeThreshold来配置

动态年龄判断

里面涉及到一个值,就是survivor区域的一半,其实也不一定是一半,你可以自定义的
参数:-XX:TargetSurvivorRatio

年龄大于阈值,进入老年代

这个阈值:JDK8后,范围是1-15
参数:XX:MaxTenuringThreshold

好了,说完了。有收获的话,记得点赞和转发哈哈哈。不然,打哭你(霸气侧漏)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值