《深入理解java虚拟机v3》3.8.4动态对象年龄判定 > 代码清单3-10

为了能更好地适应不同程序的内存状况,HotSpot虚拟机并不是永远要求对象的年龄必须达到-XX:MaxTenuringThreshold才能晋升老年代,如果在Survivor空间中相同年龄所有对象大小的总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无须等到-XX:MaxTenuringThreshold中要求的年龄。

例如Survivor区域里现在有一批对象,年龄1+年龄2+年龄n的多个年龄对象总和超过了Survivor区域的50%,此时就会把年龄n(含)以上的对象都放入老年代。源自jDK1.8源码逻辑

这个规则其实是希望那些可能是长期存活的对象,尽早进入老年代。

对象动态年龄判断机制一般是在minor gc之后触发的。

执行代码清单3-10中的testTenuringThreshold2()方法,并将设置-XX:MaxTenuring-Threshold=15,发现运行结果中Survivor占用仍然为0%,而老年代比预期增加了6%,也就是说allocation1、allocation2 对象都直接进入了老年代,并没有等到15岁的临界年龄。因为这两个对象加起来已经到达了512KB,并且它们是同年龄的,满足同年对象达到Survivor空间一半的规则,此时Survivor是1M。

我们只要注释掉其中一个对象的new操作,就会发现另外一个就不会晋升到老年代了。

	private static final int _1MB = 1024 * 1024;

	/**
	 * verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails
	 * -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15
	 * -XX:+PrintTenuringDistribution -XX:+UseSerialGC
	 */
	public static void testTenuringThreshold2() {
		byte[] allocation1, allocation2, allocation3, allocation4;
		allocation1 = new byte[_1MB / 4]; // allocation1+allocation2>512k
		allocation2 = new byte[_1MB / 4];
		allocation3 = new byte[4 * _1MB];
		allocation4 = new byte[4 * _1MB];
		allocation4 = null;
		allocation4 = new byte[4 * _1MB];
	}

	public static void main(String[] args) {
		testTenuringThreshold2();
	}

运行结果:

[`GC` [DefNew
Desired survivor size 524288 bytes, new threshold 1 (`max 15`)      `正常情况下15次存活后才会进入老年代` 
- age   1:     675200 bytes,     675200 total
: 4951K->659K(9216K), 0.0260421 secs] 4951K->4755K(19456K), 0.0260861 secs] [Times: user=0.00 sys=0.03, real=0.03 secs] 
[`GC` [DefNew
Desired survivor size 524288 bytes, new threshold 15 (max 15)
: 4755K->0K(9216K), 0.0018234 secs] 8851K->4755K(19456K), 0.0018662 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
 def new generation   total 9216K, used 4259K [0x32360000, 0x32d60000, 0x32d60000)
  eden space 8192K,  52% used [0x32360000, 0x32788fe0, 0x32b60000)
  from space 1024K,   `0% used` [0x32b60000, 0x32b60000, 0x32c60000)   `survivor 使用0,说明经过2次gc提前进入到老年代`
  to   space 1024K,   0% used [0x32c60000, 0x32c60000, 0x32d60000)
 tenured generation   total 10240K, used 4755K [0x32d60000, 0x33760000, 0x33760000)
   the space 10240K,  46% used [0x32d60000, 0x33204d90, 0x33204e00, 0x33760000)
 compacting perm gen  total 12288K, used 380K [0x33760000, 0x34360000, 0x37760000)
   the space 12288K,   3% used [0x33760000, 0x337bf128, 0x337bf200, 0x34360000)
    ro space 10240K,  51% used [0x37760000, 0x37c925d0, 0x37c92600, 0x38160000)
    rw space 12288K,  55% used [0x38160000, 0x387fd978, 0x387fda00, 0x38d60000)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值