我正在探索在具有大量 RAM 的机器上运行 Java 应用程序的可能性(从 300GB 到 15TB,可能在 SGI Altix 4700 机器上),我很好奇 Java 的 GC 可能如何执行在这种情况下。
我听说 IBM 或 JRockit 的 JVM 可能比 Sun 的更适合这个。有谁知道在这种情况下有关 JVM 性能的任何研究或数据?
我正在探索在具有大量 RAM 的机器上运行 Java 应用程序的可能性(从 300GB 到 15TB,可能在 SGI Altix 4700 机器上),我很好奇 Java 的 GC 可能如何执行在这种情况下。
我听说 IBM 或 JRockit 的 JVM 可能比 Sun 的更适合这个。有谁知道在这种情况下有关 JVM 性能的任何研究或数据?
在 Sun JVM 上,您可以使用选项 -XX:UseConcMarkSweepGC 来打开 Concurrent mark and sweep Collector,这将几乎完全避免默认 GC 算法的“stop the world”阶段,但代价是多一点高架。
恕我直言,在此类机器上使用超过 VM 的建议已过时。在现实世界的应用程序中,您通常拥有足够的共享数据,因此 CMS 和一个 JVM 的性能会更好。
问题是:您是否要在单个进程 (JVM) 中运行?如果你这样做了,那么你就会有问题。请参阅Tuning Java Virtual Machines、Oracle Coherence 用户指南和类似文档。我的经验法则是尽量避免大于 1GB 的堆。而 512MB-1GB 的完整 GC 可能需要不到一秒钟的时间。2-4GB 的完整 GC 可能需要 5 秒或更长时间。显然这取决于许多因素,但故事的寓意是 GC 开销不会线性扩展,一旦进入一秒范围,性能就会迅速下降。
Sun 的 JVM 允许您配置和优化垃圾收集,但这本身就是一门科学:http: //java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html
你可能需要做一些阅读和研究,但对于那种机器,为机器和应用程序优化的 GC 设置可能会产生很大的不同。
从 5.0 开始,Hotspot JVM 使用一个称为 Ergonomics 的概念来尝试优化内存使用。这不仅仅基于可用的内存量和影响堆大小、生成大小和垃圾收集算法。
首先阅读此内容,其中解释了人体工程学等:
https://www.oracle.com/technetwork/java/javase/memorymanagement-whitepaper-150215.pdf
还有一个叫 Brian Goetz 的人写了很多关于 Java 如何分配和使用内存的文章,所有这些文章以及更多可以在这里找到:
这根本不是在回答您的问题,但如果您计划部署一个巨大的 Java 应用程序,您可能有兴趣研究Azul Systems 设备。他们说能够在不造成应用程序暂停的情况下进行垃圾收集,最高可达单个 670 GB 堆。
您可能需要考虑在这台机器上运行一个虚拟Terracotta集群。
唯一能真正告诉你的是SGI。超级计算机的行为不像普通服务器,只是更大。
但是,我发现当内存位于访问它的处理器的本地时,Java 的性能最好。注意:GC 需要能够端到端地遍历整个内存。这意味着如果您的设计就像许多计算机粘在一起,那么它就不能很好地扩展,这可能就是这种情况。内存模块大小为 32 GB,因此如果您将 JVM 限制为舒适地适应此大小,您可能会获得更好的性能。
这篇文章的公认答案相当陈旧,现在已经过时了。截至 2014 年 9 月,如果您使用的是 Java 7,您可能应该切换到 GC1 收集器。从 Java 7 更新 4 发行说明:
http://www.oracle.com/technetwork/java/javase/7u4-relnotes-1575007.html
“G1 收集器的目标是充分利用当今多处理器服务器中可用的大量内存,同时仍控制垃圾收集延迟的应用程序。需要大堆、具有大活动数据集、突发或非统一的工作负载或遭受垃圾收集引起的长时间延迟应该从切换到 G1 中受益。”
当然,关于 GC 将如何执行的答案是“谁在乎?” ;-)