我编写了一些基于 Java 的单线程基因组学软件,一次只处理一个样本,而且我有数百个样本要处理。我可以访问一台有 64 个 CPU 和 1 TB RAM 的机器,并且系统上没有其他用户。每次调用请求的最大堆大小为 8 GB。我希望我应该能够同时调用我的代码的 30 个实例(假设有两个线程——我的主线程和一个 GC 线程?)。我一次只尝试发送 20 个(使用 makefile 和 -j20 参数)。然而,在实践中,只有 5 次运行。其余的失败并显示消息:
# There is insufficient memory for the Java Runtime Environment to continue.
# Cannot create GC thread. Out of system resources.
我怀疑这更多地与同时调用有关,而不是实际资源限制,因此我在我的程序每次调用的执行循环中实现了随机几秒的延迟。这使我最多可以同时运行 10 个程序,而不是 5 个,并显示相同的失败消息。
问题:
为什么尝试以这种方式同时调用数十个 JVM 实例会失败,尽管在显然具有可用资源的系统上这样做?
为什么我的 hack 实现调度延迟解决了一些问题?
让所有 20 个实例同时运行的更好方法是什么?
最佳答案
默认收集器是多线程的,其线程数根据 CPU 核心数进行缩放。如果您一次运行许多 Java 实例并且每个实例只有一个线程,您可能希望切换到串行收集器,这将消耗更少的线程和线程堆栈的虚拟内存。
此外,JVM 预先保留了大量虚拟内存,可能比它在其生命周期内实际需要的更多。因此,您应该启用交换并允许过度使用以避免资源耗尽。
关于java - 尝试在高内存、多 CPU 服务器上运行多个调用时 JVM 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35275289/