【发布时间】:2014-04-30 08:23:40
【问题描述】:
我有一个执行大量内存分配的多线程程序。在四核 i7 CPU 上性能很好,速度提升约为 3.9 倍。但是,当程序在 12 核 Xeon CPU 上执行时,加速值不会超过 5.5X。
我应该提到 GC 似乎不是问题,因为 VisualGC 在执行 100 多秒后报告 GC 低于 1 秒。主要内存使用属于堆的伊甸园部分,其他部分几乎没有使用。该代码执行大量 int 数组分配并对其执行一些算术运算。这有点像状态空间的探索和新实例的分配是不可避免的。
如您所知,Windows 和 Linux 的标准内存分配器对于多线程程序的性能并不令人满意,而 tcmalloc 和 Hoard 等良好的替代方案可用于 C/C++。由于并行部分由完全独立的任务组成,GC时间非常低,我怀疑主要原因应该是JVM内存分配器在太多线程竞争分配时性能不佳。
有没有人在大型多线程程序中使用 JVM 分配器的经验,并且可以就如何克服这个问题给出建议??
附:我已经使用 JVM 6,7 和 8 测试了代码。分配率也非常高(大约每秒 1000 万次),但正如我所提到的,Eden 部分被大量使用,工作集小于千兆字节。
【问题讨论】:
-
我将从分析应用程序开始。
-
我没有任何支持,但我很确定 JVM 为每个线程请求大块内存,然后每个线程从该块执行本地分配。除非您正在分配大量巨大的对象,否则这应该会表现得很好。我相信更熟悉 JVM 内部的人可以提供更多详细信息(如果我错了,请纠正我)。
-
@AndrewLogvinov 我已经对代码进行了分析,正如我所提到的,GC 的开销不到 1%,并且代码充分利用了 i7 CPU 中的内核。
-
@SaeedShahrivari 你现在期待 12 倍左右吗?
-
@Vipin 实际上,不是 12X 而是 5.5X 也没有希望。因为,代码完全是计算密集型的,工作集完全可以放入缓存中。
标签: java multithreading memory-management jvm