Java 的 ActiveProcessorCount 是否限制 JVM 可以使用的 CPU 数量?

Joh*_*egg 8 java jvm-hotspot

我正在使用 Oracle 的 Java 1.8.0_231。

设置-XX:ActiveProcessorCount=n有什么作用?我不是 C++ 人员,但我想我在 HotSpot 源代码中看到了这两个用途:

  • 影响 HotSpot 编译器线程数
  • 影响GC线程数

然而,它实际上限制了 JVM 可以使用的 CPU 数量吗?Java 10 发行说明明确指出:

此外,此更改添加了一个 JVM 选项,可以指定 JVM 将使用的 CPU 数量。

我担心的是,我的测试结果(在任何 Docker、CF 等容器之外)似乎显示应用程序平等地使用所有 8 个 CPU,而不是我设置的 4 个: 所有 8 个 CPU

那么,设置 ActiveProcessorCount 实际上应该限制 JVM 使用的 CPU 数量吗?我在 HotSpot 代码中没有看到任何这样做的内容,而且我的测试结果似乎也说不。

谢谢

kbo*_*ino 8

为了补充Mena的其他答案并证明Kayaman的评论,该参数的直接作用是设置返回的值Runtime.getRuntime().availableProcessors()

为了证明这一点,我创建了一个类

public class Main {
    public static void main(String[] args) {
        System.out.println("Runtime.getRuntime().availableProcessors() = " +
                Runtime.getRuntime().availableProcessors());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我在 12 核机器上使用 Java 11 编译并运行它,并使用了一些不同的选项:

# Show the version of Java in use
$ java -version
openjdk version "11.0.6" 2020-01-14
OpenJDK Runtime Environment (build 11.0.6+10)
OpenJDK 64-Bit Server VM (build 11.0.6+10, mixed mode)

# Run with defaults
$ java -cp . Main
Runtime.getRuntime().availableProcessors() = 12

# Run with limit lower than actual number of cores
$ java -XX:ActiveProcessorCount=4 -cp . Main 
Runtime.getRuntime().availableProcessors() = 4

# Run with limit higher than actual number of cores
$ java -XX:ActiveProcessorCount=20 -cp . Main 
Runtime.getRuntime().availableProcessors() = 20
Run Code Online (Sandbox Code Playgroud)

这也适用于最新版本的 Java 8,特别是 OpenJDK 1.8.0_242-b08。

如前所述,这有助于调整线程池的大小,但不会对可以使用的 CPU 核心数量施加任何硬性限制。


Men*_*ena 6

不是专家,但将文档解释为简单的英语:

覆盖虚拟机用于计算用于各种操作(例如垃圾收集和 ForkJoinPool)的线程池大小的 CPU 数量。

这告诉我,它并不是要限制运行时的核心使用,而是“计算线程池的大小[...]”。

因此,如果您使用一半的可用 CPU 进行参数化,这些 JVM 任务的线程池将会更小,但这不会影响整个应用程序在运行时的 CPU 利用率。

注意事项

  1. 我找到的文档的唯一版本是针对 Java 11 的,因此这是否在 v.8、10 和 11 之间发生了根本性的变化可能有待解释(阅读:我不知道)。
  2. 此外,您提到的 java 10发行说明向我表明该选项在 Java 8 中可能根本不可用,因此不起作用。

  • 也许它只会影响“Runtime.getRuntime().availableProcessors();”,它通常用于各种池大小调整和其他此类计算。 (3认同)