Java:限制 JVM 可以使用的核心数量

Java:限制 JVM 可以使用的核心数量

多个用户在 60 核计算服务器(基于 Linux/Ubuntu)上运行 Java 应用程序。有不同的应用程序,其中大多数不是内部开发的。

虽然系统管理员认为特定用户的 Java 进程在任意时刻使用 10 个核心是可以的,但她希望他们使用的核心不要超过 10 个。

是否有任何 Java 或 OS 配置可用于防止该进程以无限制的方式抓取计算资源?

答案1

在操作系统方面:

  • 我想说的经典方法是用设置 CPU 亲和性taskset

  • 更好的选择是使用cgroups

  • 流行的解决方案是在Docker容器。然而,在 Java 8 之前,JVM 无法理解 Docker 施加的限制(仅在 8u131+ 反向移植后可用,不确定它是否在 Java9 中作为 CPU 部分的实验性功能可用,但它适用于内存,在 Java10 中完全可用)

答案2

我想说,这个视频值得一看。https://vimeo.com/181900266

它对 Java、cgroups 和容器进行了很好的概述,以及 JVM 如何找出 CPU 的数量。

基于此,我想说,直到 Java 8,JVM 都会确定可用的 CPU 数量,它始终认为所有“在线”CPU 都可用,因为它为此使用了 sysconf(_SC_NPROCESSORS_ONLN)。即使它是 cgroup 或放入容器中。

从 Java 9 开始,JVM 将使用 sched_getaffinity(),如果使用 cpuset 来控制 JVM 的 CPU 数量,它将有所帮助。即 JVM 将仅看到已配置的 CPU。例如,如果使用 Docker 的 cpuset-cpus 选项,那么它将真正为 JVM 创建限制。注意!如果为 JVM 配置了 cpushare,这仍然不能解决问题。如果仅配置了 cpushare,JVM 仍将看到系统中的所有 CPU(无论它是否在容器中)。

答案3

除了其他人提到的(cgroup 配额、cgroup cpuset)之外,另一种选择是,您可以通过为选项提供一个值来明确告诉 Java 在库询问时应该报告多少个 CPU -XX:ActiveProcessorCount。任何根据值自动选择线程数的库Runtime.getRuntime().availableProcessors()(例如 Reactor 的Schedulers.parallel())都将相应地进行配置。它还可能通知垃圾收集器的自动配置。

相关内容