Java自动内存管理机制学习(二):垃圾回收器与内存分配策略 (10)

以MaxTenuringThreshold=15参数来运行的结果:

[GC [DefNew Desired Survivor size 524288 bytes, new threshold 15 (max 15) - age 1: 414664 bytes, 414664 total : 4859K->404K(9216K), 0.0049637 secs] 4859K->4500K(19456K), 0.0049932 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC [DefNew Desired Survivor size 524288 bytes, new threshold 15 (max 15) - age 2: 414520 bytes, 414520 total : 4500K->404K(9216K), 0.0008091 secs] 8596K->4500K(19456K), 0.0008305 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] Heap def new generation total 9216K, used 4582K [0x029d0000, 0x033d0000, 0x033d0000) eden space 8192K, 51% used [0x029d0000, 0x02de4828, 0x031d0000) from space 1024K, 39% used [0x031d0000, 0x03235338, 0x032d0000) to space 1024K, 0% used [0x032d0000, 0x032d0000, 0x033d0000) tenured generation total 10240K, used 4096K [0x033d0000, 0x03dd0000, 0x03dd0000) the space 10240K, 40% used [0x033d0000, 0x037d0010, 0x037d0200, 0x03dd0000) compacting perm gen total 12288K, used 2114K [0x03dd0000, 0x049d0000, 0x07dd0000) the space 12288K, 17% used [0x03dd0000, 0x03fe0998, 0x03fe0a00, 0x049d0000) No shared spaces configured.

 

动态对象年龄判定

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

执行下面代码中的testTenuringThreshold2()方法,并设置-XX:MaxTenuringThreshold=15,会发现运行结果中Survivor的空间占用仍然为0%,而老年代比预期增加了6%,也就是说,allocation1、allocation2对象都直接进入了老年代,而没有等到15岁的临界年龄。因为这两个对象加起来已经到达了512KB,并且它们是同年的,满足同年对象达到Survivor空间的一半规则。我们只要注释掉其中一个对象new操作,就会发现另外一个就不会晋升到老年代中去了。

private static final int _1MB = 1024 * 1024; /** * VM参数:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=15 * -XX:+PrintTenuringDistribution */ @SuppressWarnings("unused") public static void testTenuringThreshold2() { byte[] allocation1, allocation2, allocation3, allocation4; allocation1 = new byte[_1MB / 4]; // allocation1+allocation2大于survivo空间一半 allocation2 = new byte[_1MB / 4]; allocation3 = new byte[4 * _1MB]; allocation4 = new byte[4 * _1MB]; allocation4 = null; allocation4 = new byte[4 * _1MB]; }

 

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zysgyg.html