Java在使用大内存堆时速度较慢。

12 浏览
0 Comments

Java在使用大内存堆时速度较慢。

我有一个操作(大型)图形的Java程序。因此,它使用了大量的堆空间(约为50GB,大约占主机机器物理内存的25%)。在程序的某个点上,它(反复地)从图中选择一个节点并对其进行一些计算。对于某些节点,这个计算所花费的时间比预期的要长得多(30-60分钟,而不是几秒钟)。为了对这些操作进行分析,找出花费了这么长时间的原因,我创建了一个测试程序,它只创建了大图的一小部分,然后在原始程序中花费很长时间计算的一个节点上运行相同的操作。因此,与原始程序相比,测试程序显然只使用了很少的堆空间。\n结果发现,在原始程序中花费了48分钟的操作在测试程序中只需要9秒钟就能完成。这真的让我很困惑。最初的想法可能是较大的程序在垃圾收集上花费了很多时间。因此,我打开了VM的垃圾收集器的详细模式。根据这个模式,48分钟内没有进行任何完整的垃圾收集,并且只有大约20次的年轻代垃圾收集,每次收集时间都不到1秒钟。\n那么我的问题是,还有什么其他原因可以解释这样巨大的时间差异呢?我对Java内部如何组织堆知之甚少。在一个具有大量活动对象的大堆中,是否有一些操作需要花费更长的时间?在这种情况下,对象分配是否需要更长时间来找到堆中的适当位置?或者虚拟机是否会对堆进行任何内部重组,这可能需要很长时间(除了垃圾收集,显然)。\n我正在使用Oracle JDK 1.7,如果这有任何重要性的话。

0
0 Comments

Java在使用大堆内存时速度较慢的原因可能是因为数据在现代CPU上存在多层缓存。每次离开缓存获取数据,速度就会变慢。拥有50GB的RAM可能意味着每次都需要离开缓存获取数据。

虽然你描述的症状和差异非常明显,但我不认为像缓存一致性这样简单的问题会导致如此大的差别。

我能给你的最好建议是,尝试在运行缓慢和运行快速时使用分析器分析它,并比较差异。

你需要准确的数字和时间。"在这种环境下,执行X操作花费了Y时间"。通过这样,你可以逐渐缩小问题的范围。

解决这个问题的方法可能是优化代码,减少对内存的频繁访问,或者使用更高效的算法和数据结构来处理大量的数据。另外,可以考虑使用并行处理或者分布式计算来提高处理速度。

0
0 Comments

Java在使用大堆内存时运行较慢的原因可能是由于交换空间的使用,即使物理内存足够,轻微的交换也可能导致严重的减速。解决方法是关闭交换空间,并检查swappiness参数。

以下是整理后的

Java在使用大堆内存时运行较慢的原因可能是由于交换空间的使用,即使物理内存足够,轻微的交换也可能导致严重的减速。解决方法是关闭交换空间,并检查swappiness参数。

大内存可能意味着更大的问题,但我认为除了排除了的GC之外,没有什么可以将9秒延长到48分钟(320倍)的因素。大堆使看似更糟糕的空间局部性成为可能,但我认为这并不重要。我不同意Tim关于“为了一切都要离开缓存”的答案。

还有一种叫做Translation Lookaside Buffer(TLB)的缓存,用于虚拟地址转换,可能会在非常大的内存中引起一些问题。但同样,不会造成320倍的因素。

我不认为JVM中有任何可能导致这种问题的东西。

我唯一能想象到的原因是你可能有一些被使用的交换空间,尽管你有足够的物理内存。即使轻微的交换也可能是减速的原因。确保关闭交换空间(并可能检查swappiness参数)。

据我所知,没有进行交换。根据你的回答,我只能推断问题出现在我的代码中。我需要进一步调查。谢谢!

你找到问题了吗?

0