Java GC 模棱两可的日志信息

4

我正在32位Windows操作系统上使用Java JRE启动Java客户端。

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

我的jar包含大量数据(双倍表,约600 MB),这些数据在整个应用程序的生命周期中都会保存在内存中。
然后,每隔一分钟左右,它会给出日志消息,如下所示:
[GC [DefNew:279616K-> 279616K(314560K),0.0002037秒][Tenured:595827K-> 599952K(699072K),1.1020398秒] 875443K-> 599952K(1013632K),[Perm:10042K-> 10042K(16384K)],1.1030218秒] [Times:user = 1.09 sys = 0.01,real = 1.11秒]
我真的不理解加粗部分。它说新一代从279616K到279616K(即没有变化),老一代略微增加(595827K-> 599952K),但总体上说是875443K-> 599952K,即减少了约30%。这怎么可能呢?

编辑:为了完全清楚,我希望如果我加上279616K+595827K=875443K,我会得到粗体的第一部分,也就是总堆大小。同样,我希望279616K+599952K将总和第二部分的粗体,但它没有。在下面指定的链接Java垃圾收集日志消息中,它会相加,所以我可能遗漏了什么。


你使用Sun JDK吗?如果是这样,你可能想要查看Java调优白皮书。其次,你能否提供更多的上下文信息?例如操作系统、进程数据模型(32位或64位)... - user670002
在我优化某些东西之前,我首先想要理解当前日志信息的含义(在我的情况下,NewRatio=4并使用并发GC修复了我的吞吐量问题)。 - Frank Meulenaar
2个回答

3
重点在于DefNewTenured是小型垃圾收集的结果,而总数还包括以下大型垃圾收集的结果。因此,在小型收集期间无法成功地收集年轻一代,只能通过大型垃圾收集来进行收集。
诊断垃圾回收问题建议检查是否年轻一代过大:Diagnosing a Garbage Collection problem。以下是示例输出:
[GC [DefNew:16000K-> 16000K(16192K),0.0000498秒] [Tenured:2535K-> 2319K(16384K),0.0860925秒] 18535K-> 2319K(32576K),0.0863350秒]
这是年轻一代相对于老年代太大以至于无法保证年轻一代晋升(年轻一代大小约为老年代的一半)的示例。年轻一代无法成功收集,只会发生主要收集。请注意,在本案例中,年轻一代被收集,但作为更昂贵的主要收集的一部分。
我猜测在你的情况下,也可能是老年代缺乏空间引起的。

谢谢,但我仍然不理解Tenured如何成为收集的一部分; 难道收集的重点不是只收集年轻代吗?如果它是小收集的一部分,为什么小收集大部分时间都花在老年代上呢? - Frank Meulenaar

1

是的,我看到了那篇帖子和原始链接,所以我尝试在我的日志中检查基本算术,但结果不符。请查看我在主贴中的编辑。 - Frank Meulenaar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接