JVM内存分配器的多线程性能

5
我有一个多线程程序,需要进行大量的内存分配。在四核i7 CPU上,性能表现良好,速度提升约为3.9倍。但是,在12核Xeon CPU上执行该程序时,加速值不超过5.5倍。
我应该提到GC似乎不是问题,因为VisualGC在100秒以上的执行后报告GC时间低于1秒。主要的内存使用归属于堆的Eden部分,其他部分几乎没有使用。代码进行了大量的int数组分配,并对它们执行一些算术操作。它有点像状态空间探索,无法避免分配新实例。
正如您所知,Windows和Linux的标准内存分配器对于多线程程序的性能表现不佳,而C/C++有好的替代方案,如tcmalloc和Hoard。由于并行部分由完全独立的任务组成,且GC时间非常短,我怀疑主要原因可能是JVM的内存分配器在太多线程竞争分配时性能不佳。
是否有人在大规模多线程程序中有JVM内存分配器的经验,并可以就如何解决这个问题给出建议?
附言:我已经测试过JVM 6、7和8的代码。分配速率也非常高(约每秒1000万次),但正如我所提到的,Eden部分被大量使用,工作集小于1 GB。

@AndrewLogvinov 我已经对代码进行了分析,正如我所提到的,GC 的开销不到 1%,而且代码充分利用了 i7 CPU 中的核心。 - Saeed Shahrivari
@Vipin 实际上,不是12X而是5.5X也不太有前途。因为,代码完全是计算密集型的,工作集完全可以放在缓存中。 - Saeed Shahrivari
@SaeedShahrivari 那么这是调优问题。你为这个计算分配了多少线程? - Vipin
@Vipin 我已经在一台12核心的机器上测试了从12到30个线程,但最佳情况是12个线程,并且性能会随着更多线程的增加而略微降低。 - Saeed Shahrivari
我几乎无法相信JVM分配是瓶颈。从堆中分配通常与仅仅碰撞指针一样快。甚至不需要原子指令,因为每个线程都有自己的分配缓冲区(TLAB)。顺便说一下,您可以使用“-XX:TLABSize = NNN” JVM选项来调整TLAB大小,并查看是否有任何差异。 - apangin
显示剩余4条评论
1个回答

0

你的情况下,伊甸园空间是否比应有的少?如果是这样,请考虑使用 -XX:NewRatio=1或其他适当的值。

为了确定这一点,请使用 -XX:+PrintTenuringDistribution 查看分布情况。


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