Windows 环境变量 NUMBER_OF_PROCESSORS 在 JVM 内部和外部显示不同的值
Windows environment variable NUMBER_OF_PROCESSORS shows different value within JVM and outside
在我们的 Windows Server 2019 上,我们有 36 个内核和 72 个逻辑处理器,如任务管理器 CPU 性能 window 所示。而且,如果在命令提示符下,如果我 运行 命令。
echo %NUMBER_OF_PROCESSORS%
它告诉我 72。
但是,在 Java 程序中,如果我 运行 下面的代码片段,
public class NoOfCPUs {
public static void main(String[] args) {
String envName = "NUMBER_OF_PROCESSORS";
String noOfP = System.getenv(envName);
System.out.format("%s (from env) = %s%n", envName, noOfP);
}
}
输出如下:
NUMBER_OF_PROCESSORS (from env) = 36
在 Netbeans IDE 中的 Windows 上使用 64 位 Java 8 编译器编译。制作了一个可执行的jar。
运行 罐子,如:
java -jar NoOfCPUs.jar
相同的系统环境变量,NUMBER_OF_PROCESSORS 显示命令提示符与 Java 程序中的不同结果。
为什么?
2009版本后Windows使用的是逻辑处理器组吗?逻辑处理器组在一个组中最多包含 64 个处理器。
这似乎与以下其他问题有关:
- How to make Java application use all CPU groups
- Java uses only 1 of 2 CPU with NUMA (Neo4J)
并且此错误报告表示将不支持(不会修复):
https://bugs.openjdk.java.net/browse/JDK-6942632
错误报告说用户应该负责将正确数量的 CPU 配置为 Java,这可以通过以下方式实现:
- https://bitsum.com/portfolio/groupextend/
- 可能是其他的,因为像 start /affinity 这样的亲和力继承,参见 this answer 但我不能 test/confirm 因为我的笔记本电脑没有那么多内核
我认为你应该考虑 运行 你的应用程序的多个实例(和 Java)而不是仅仅一个以获得最大性能,因为 NUMA 局部性,尽管不同 Java 虚拟机器有 support for NUMA it still might have scalability issues depending on the configured Garbage Collection algorithm (non-concurrent, thus Stop-the-World) see: Amdahls Law
如果该限制特定于 HotSpotVM(源自 Sun/Oracle),您可能需要查看不同的 Java 虚拟机 OpenJ9(源自 IBM)和其他 Azul Zing JVM
如果它是 Windows 特定限制,您可能需要考虑切换到不同的操作系统或 运行 通过您选择的管理程序 Windows 的多个实例。
在我们的 Windows Server 2019 上,我们有 36 个内核和 72 个逻辑处理器,如任务管理器 CPU 性能 window 所示。而且,如果在命令提示符下,如果我 运行 命令。
echo %NUMBER_OF_PROCESSORS%
它告诉我 72。
但是,在 Java 程序中,如果我 运行 下面的代码片段,
public class NoOfCPUs {
public static void main(String[] args) {
String envName = "NUMBER_OF_PROCESSORS";
String noOfP = System.getenv(envName);
System.out.format("%s (from env) = %s%n", envName, noOfP);
}
}
输出如下:
NUMBER_OF_PROCESSORS (from env) = 36
在 Netbeans IDE 中的 Windows 上使用 64 位 Java 8 编译器编译。制作了一个可执行的jar。 运行 罐子,如:
java -jar NoOfCPUs.jar
相同的系统环境变量,NUMBER_OF_PROCESSORS 显示命令提示符与 Java 程序中的不同结果。
为什么?
2009版本后Windows使用的是逻辑处理器组吗?逻辑处理器组在一个组中最多包含 64 个处理器。
这似乎与以下其他问题有关:
- How to make Java application use all CPU groups
- Java uses only 1 of 2 CPU with NUMA (Neo4J)
并且此错误报告表示将不支持(不会修复):
https://bugs.openjdk.java.net/browse/JDK-6942632
错误报告说用户应该负责将正确数量的 CPU 配置为 Java,这可以通过以下方式实现:
- https://bitsum.com/portfolio/groupextend/
- 可能是其他的,因为像 start /affinity 这样的亲和力继承,参见 this answer 但我不能 test/confirm 因为我的笔记本电脑没有那么多内核
我认为你应该考虑 运行 你的应用程序的多个实例(和 Java)而不是仅仅一个以获得最大性能,因为 NUMA 局部性,尽管不同 Java 虚拟机器有 support for NUMA it still might have scalability issues depending on the configured Garbage Collection algorithm (non-concurrent, thus Stop-the-World) see: Amdahls Law
如果该限制特定于 HotSpotVM(源自 Sun/Oracle),您可能需要查看不同的 Java 虚拟机 OpenJ9(源自 IBM)和其他 Azul Zing JVM
如果它是 Windows 特定限制,您可能需要考虑切换到不同的操作系统或 运行 通过您选择的管理程序 Windows 的多个实例。