我正在使用32位Windows上的Java JRE启动Java客户端,

java -Xmx1024m -Xms1024m -verbose:gc -XX:+PrintGCDetails -jar myJar.jar

我的jar包含很多数据(双打表,600ish MB),这些数据在应用程序的整个生命周期中都保留在内存中。

然后,它大约每分钟给出记录消息,内容为:

[GC [DefNew:279616K-> 279616K(314560K),0.0002037秒] [使用时间:595827K-> 599952K(699072K),1.1020398秒] 875443K-> 599952K (1013632K),[Perm:10042K-> 10042K(16) ],1.1030218秒] [时间:用户= 1.09 sys = 0.01,真实= 1.11秒]

我真的不明白大胆的部分。它说新一代从279616K增长到279616K(即什么都没有改变),老一代则略有增加(595827K-> 599952K),但总的说来是875443K-> 599952K,即减少了约30%。怎么会这样?

编辑:完全清楚,我希望如果我加上279616K + 595827K = 875443K,则第一部分将以粗体显示,即总堆大小。同样,我期望279616K + 599952K将第二部分加粗,但事实并非如此。在下面指定的Java Garbage Collection Log messages链接中,它确实累加了,所以我可能丢失了一些内容。

最佳答案

关键是DefNewTenured是次要集合的结果,而总数也包括以下主要集合的结果。因此,在次要收藏期间无法成功收集年轻一代,而只能由主要收藏收集。
Diagnosing a Garbage Collection problem建议这可能是由于年轻一代过大造成的:

[GC [DefNew:16000K-> 16000K(16192K),0.0000498秒] [使用期限:2535K-> 2319K(16384K),0.0860925秒] 18535K-> 2319K(32576K),0.0863350秒]
这是一个例子,即年轻一代与终身一代的相对规模太大而无法保证年轻一代的晋升(年轻一代大约是终身一代的一半)。年轻一代无法被成功收集,只有主要的收集正在发生。请注意,由于这个原因,年轻一代被收集,但仅作为更昂贵的主要收藏的一部分。

我想在您的情况下,这也可能是由终身任职的一代中缺乏可用空间引起的。

07-28 06:42