最近在看JVM相关的资料的时候提到了一个空间分配担保的问题,大体意思就是:
在1.6 update24之前,在发生minor GC前虚拟机会检查老年代最大的可用的连续空间是否大于年轻代所有对象的总和,弱国这个条件成立,则MinorGC是安全的。如果不成立,则虚拟机查看HandlePronotionFailure是否设置允许担保失败,如果允许则继续检查老年代最大的连续可用空间是否大于历次进入来年代对象的平均大小,如果大于,则尝试MinorGC。如果不满足上面任何一个条件则Full
GC。
但是1.6 update24之后 HandelPromotionFailure已经失效,放弃。但是还是有一点困惑。上代码。
public class Demo {
// JVM 参数
// -XX:+PrintGC
// -XX:+PrintGCDetails
// -Xms20m
// -Xmn10m
// -Xmx20m
// -XX:+UseSerialGC
// -XX:MaxTenuringThreshold=15
// -XX:-HandlePromotionFailure
// -XX:+PrintHeapAtGC
public static void main(String[]args)
{
byte []a =new byte[6*1024*1024];
byte []a1 =new byte[5*1024*1024];
a1=null;
byte []a2 =new byte[4*1024*1024];
}
}
在a1分配时会出发Minor GC。在a2分配时,发现Young空间不足,按照上面步骤检查,发现Old区剩余空间不足,且每次进入Old区空间的对象大小大于剩余空间。出发Full GC。
问题来了,出发Full GC后年轻代的a1是怎么被回收的?
下面贴出日志
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option HandlePromotionFailure; support was removed in 6.0_24
{Heap before GC invocations=0 (full 0):
def new generation total 9216K, used 6815K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
eden space 8192K, 83% used [0x00000000f9a00000, 0x00000000fa0a7e38, 0x00000000fa200000)
from space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000)
to space 1024K, 0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)
tenured generation total 10240K, used 0K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
the space 10240K, 0% used [0x00000000fa400000, 0x00000000fa400000, 0x00000000fa400200, 0x00000000fae00000)
compacting perm gen total 21248K, used 2708K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
the space 21248K, 12% used [0x00000000fae00000, 0x00000000fb0a51d0, 0x00000000fb0a5200, 0x00000000fc2c0000)
No shared spaces configured.
[GC[DefNew: 6815K->475K(9216K), 0.0052078 secs] 6815K->6619K(19456K), 0.0052389 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap after GC invocations=1 (full 0):
def new generation total 9216K, used 475K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
eden space 8192K, 0% used [0x00000000f9a00000, 0x00000000f9a00000, 0x00000000fa200000)
from space 1024K, 46% used [0x00000000fa300000, 0x00000000fa376d90, 0x00000000fa400000)
to space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000)
tenured generation total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
the space 10240K, 60% used [0x00000000fa400000, 0x00000000faa00010, 0x00000000faa00200, 0x00000000fae00000)
compacting perm gen total 21248K, used 2708K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
the space 21248K, 12% used [0x00000000fae00000, 0x00000000fb0a51d0, 0x00000000fb0a5200, 0x00000000fc2c0000)
No shared spaces configured.
}
{Heap before GC invocations=1 (full 0):
def new generation total 9216K, used 5923K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
eden space 8192K, 66% used [0x00000000f9a00000, 0x00000000f9f51f88, 0x00000000fa200000)
from space 1024K, 46% used [0x00000000fa300000, 0x00000000fa376d90, 0x00000000fa400000)
to space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000)
tenured generation total 10240K, used 6144K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
the space 10240K, 60% used [0x00000000fa400000, 0x00000000faa00010, 0x00000000faa00200, 0x00000000fae00000)
compacting perm gen total 21248K, used 2711K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
the space 21248K, 12% used [0x00000000fae00000, 0x00000000fb0a5d58, 0x00000000fb0a5e00, 0x00000000fc2c0000)
No shared spaces configured.
//GC日志,DefNew回收前后没有变化
[GC[DefNew: 5923K->5923K(9216K), 0.0000090 secs][Tenured: 6144K->6616K(10240K), 0.0037974 secs] 12067K->6616K(19456K), [Perm : 2711K->2711K(21248K)], 0.0038378 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap after GC invocations=2 (full 1):
//GC后年轻代 使用为0
def new generation total 9216K, used 0K [0x00000000f9a00000, 0x00000000fa400000, 0x00000000fa400000)
eden space 8192K, 0% used [0x00000000f9a00000, 0x00000000f9a00000, 0x00000000fa200000)
from space 1024K, 0% used [0x00000000fa300000, 0x00000000fa300000, 0x00000000fa400000)
to space 1024K, 0% used [0x00000000fa200000, 0x00000000fa200000, 0x00000000fa300000)
tenured generation total 10240K, used 6616K [0x00000000fa400000, 0x00000000fae00000, 0x00000000fae00000)
the space 10240K, 64% used [0x00000000fa400000, 0x00000000faa76290, 0x00000000faa76400, 0x00000000fae00000)
compacting perm gen total 21248K, used 2711K [0x00000000fae00000, 0x00000000fc2c0000, 0x0000000100000000)
the space 21248K, 12% used [0x00000000fae00000, 0x00000000fb0a5d58, 0x00000000fb0a5e00, 0x00000000fc2c0000)
No shared spaces configured.
}
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option HandlePromotionFailure; support was removed in 6.0_24
验证了HandelPromotionFailure已经不被支持了。
最后一次FullGC后从GC的日志上来看,年轻代的a1并没有被清除,但是FullGC后的堆信息显示,a1被清除了,Young取使用空间为0.
请教a1是怎么被清除的?实在很困扰