gpt4 book ai didi

java - 如何在运行并行 Java 进程时防止物理内存消耗

转载 作者:搜寻专家 更新时间:2023-11-01 02:03:15 26 4
gpt4 key购买 nike

我有一些函数的大列表(最多 500 000 个)。我的任务是为每个函数生成一些图形(它可以独立于其他函数执行)并将输出转储到文件(可以是多个文件)。生成图表的过程可能很耗时。

我的服务器也有 40 个物理内核和 128GB 内存。

我尝试过使用 java Threads/ExecutorPool 实现并行处理,但似乎没有使用处理器的所有资源。在某些输入上,程序最多需要 25 小时才能运行,并且根据 htop 只有 10-15 个内核在工作。

所以我尝试的第二件事是创建 40 个不同的进程(使用 Runtime.exec)并在它们之间拆分列表。此方法使用处理器的所有资源(所有 40 个内核上的 100% 负载)并在前面的示例中将性能提高 5 倍(只需要 5 个小时,这对我的任务来说是合理的)。 但是这种方法的问题是,每个java进程都是独立运行的,并且独立于其他进程消耗内存。在某些情况下,所有 128gb 的 ram 在并行工作 5 分钟后都被消耗掉了。我现在使用的一种解决方案是,如果 Runtime.totalMemory > 2GB,则为每个进程调用 System.gc()。这会稍微降低整体性能(之前的输入为 8 小时),但将内存使用量保持在合理的范围内。但此配置仅适用于我的服务器。如果在40核64GB的服务器上运行,需要调Runtime.totalMemory > 2GB条件。

所以问题是避免这种过度内存消耗的最佳方法是什么?

运行单独的进程来执行并行作业是正常做法吗?

Java 中是否有任何其他并行方法(可能是 fork/join?)使用 100% 的处理器物理资源。

最佳答案

您不需要显式调用 System.gc()! JVM 会在需要时自动执行,而且几乎总是做得更好。但是,您应该将最大堆大小 (-Xmx) 设置为一个合适的数字。

如果您的程序无法进一步扩展,您就会遇到某种拥塞。您可以分析您的程序以及您的 Java 和系统设置并找出原因,或者将其作为多个进程运行。如果每个进程都是多线程的,那么使用 5-10 个进程而不是 40 个可能会获得更好的性能。

请注意,您可能通过每个核心多个线程获得更高的性能。摆弄每个内核 1-8 个线程,看看吞吐量是否增加。

根据您的描述,听起来您有 500,000 个完全独立的工作项,而且每个工作项实际上并不需要大量内存。如果这是真的,那么内存消耗就不是真正的问题。只要每个进程都有足够的内存,所以它不必经常进行 gc,那么 gc 就不会对总执行时间产生太大影响。只需确保您没有任何对不再需要的对象的悬空引用。

关于java - 如何在运行并行 Java 进程时防止物理内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40460032/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com