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.