3.6.3 长期存活的对象将进入老年代
既然虚拟机采用了分代收集的思想来管理内存,那么内存回收时就必须能识别哪些对象应放在新生代,哪些对象应放在老年代中。为了做到这点,虚拟机给每个对象定义了一个对象年龄(Age)计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的话,将被移动到Survivor空间中,并且对象年龄设为1。对象在Survivor区中每“熬过”一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁),就将会被晋升到老年代中。对象晋升老年代的年龄阈值,可以通过参数-XX:MaxTenuringThreshold设置。
读者可以试试分别以-XX:MaxTenuringThreshold=1和-XX:MaxTenuringThreshold=15两种设置来执行代码清单3-7中的testTenuringThreshold()方法,此方法中的allocation1对象需要256KB内存,Survivor空间可以容纳。当MaxTenuringThreshold=1时,allocation1对象在第二次GC发生时进入老年代,新生代已使用的内存GC后非常干净地变成0KB。而MaxTenuringThreshold=15时,第二次GC发生后,allocation1对象则还留在新生代Survivor空间,这时新生代仍然有404KB被占用。
代码清单3-7 长期存活的对象进入老年代
private static final int_1MB=1024*1024;
/**
*VM参数:-verbose:gc-Xms20M-Xmx20M-Xmn10M-XX:+PrintGCDetails-XX:SurvivorRatio=8-XX:MaxTenuringThreshold=1
*-XX:+PrintTenuringDistribution
*/
@SuppressWarnings("unused")
public static void testTenuringThreshold(){
byte[]allocation1,allocation2,allocation3;
allocation1=new byte[_1MB/4];
//什么时候进入老年代取决于XX:MaxTenuringThreshold设置
allocation2=new byte[4*_1MB];
allocation3=new byte[4*_1MB];
allocation3=null;
allocation3=new byte[4*_1MB];
}
以MaxTenuringThreshold=1参数来运行的结果:
[GC[DefNew
Desired Survivor size 524288 bytes,new threshold 1(max 1)
-age 1:414664 bytes,414664 total
:4859K->404K(9216K),0.0065012 secs]4859K->4500K(19456K),0.0065283 secs][Times:user=0.02 sys=0.00,real=0.02 secs]
[GC[DefNew
Desired Survivor size 524288 bytes,new threshold 1(max 1)
:4500K->0K(9216K),0.0009253 secs]8596K->4500K(19456K),0.0009458 secs][Times:user=0.00 sys=0.00,real=0.00 secs]
Heap
def new generation total 9216K,used 4178K[0x029d0000,0x033d0000,0x033d0000)
eden space 8192K,51%used[0x029d0000,0x02de4828,0x031d0000)
from space 1024K,0%used[0x031d0000,0x031d0000,0x032d0000)
to space 1024K,0%used[0x032d0000,0x032d0000,0x033d0000)
tenured generation total 10240K,used 4500K[0x033d0000,0x03dd0000,0x03dd0000)
the space 10240K,43%used[0x033d0000,0x03835348,0x03835400,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=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.