Java速度慢且堆大

格奥尔格

我有一个在(大)图上运行的Java程序。因此,它使用了大量的堆空间(约50GB,约占主机物理内存的25%)。一方面,程序(反复地)从图中选择一个节点并对其进行一些计算。对于某些节点,此计算所花费的时间比预期的要长得多(30-60分钟,而不是预期的几秒钟)。为了剖析这些操作以找出耗时的时间,我创建了一个测试程序,该程序仅创建大图的一小部分,然后在需要花费很长时间进行计算的节点之一上运行相同的操作原始程序。因此,与原始程序相比,测试程序显然仅使用很少的堆空间。

事实证明,在原始程序中花费48分钟的操作可以在测试程序中在9秒内完成。这真的让我感到困惑。第一个想法可能是较大的程序在垃圾回收上花费了大量时间。因此,我打开了VM垃圾收集器的详细模式。据此,在48分钟内没有执行完整的垃圾收集,而在年轻一代中仅进行了大约20次收集,每个收集所用的时间不到1秒。

所以我的问题是,还有什么可以解释如此巨大的时间差异?我不太了解Java在内部如何组织堆。对于具有大量活动对象的大型堆,是否需要花费更长的时间?在这样的设置下,对象分配是否可能会花费更长的时间,因为在堆中找到适当的位置会花费更长的时间?还是VM进行了可能需要很多时间的堆内部重组(显然,除了垃圾回收之外)。

如果有任何重要意义,我正在使用Oracle JDK 1.7。

马塔蒂努斯

虽然更大的内存可能意味着更大的问题,但我想说的是(除了您已排除的GC外)没有什么可以将9秒延长到48分钟(320倍)。

大堆可能使看似更差的空间局部性成为可能,但我认为这并不重要。我不同意蒂姆的回答“必须为所有内容保留缓存”。

还有TLB,该缓存用于虚拟地址转换,这可能会在很大的内存上引起一些问题。但是同样,不是320因子。

我认为JVM中没有任何可能引起此类问题的东西。

我可以想象的唯一原因是,尽管您有足够的物理内存,但您仍有一些交换空间被使用。甚至很小的交换也可能是造成严重减速的原因。确保已关闭(并可能检查swappiness)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章