Java 8与Java 11中availableProcessors()返回CPU数不一致问题咨询
Java 8与Java 11检测CPU数量不一致的原因分析
问题场景
在Linux集群中运行程序时,发现Java检测到的CPU数量(ncpus=1)与nproc命令显示的(ncpus=32)不符,为此编写了如下测试程序:
import java.lang.management.*; public class Test { public static void main(String args[]) throws Exception { OperatingSystemMXBean op = (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean(); System.err.println("A - CPUS: " + op.getAvailableProcessors()); System.err.println("B - CPUS: " + java.lang.Runtime.getRuntime().availableProcessors()); } }
Java 11运行输出
$ java -version && javac Test.java && java Test openjdk version "11.0.8-internal" 2020-07-14 OpenJDK Runtime Environment (build 11.0.8-internal+0-adhoc..src) OpenJDK 64-Bit Server VM (build 11.0.8-internal+0-adhoc..src, mixed mode) A - CPUS: 1 B - CPUS: 1
Java 8运行输出
$ java -version && javac Test.java && java Test openjdk version "1.8.0_112" OpenJDK Runtime Environment (Zulu 8.19.0.1-linux64) (build 1.8.0_112-b16) OpenJDK 64-Bit Server VM (Zulu 8.19.0.1-linux64) (build 25.112-b16, mixed mode) A - CPUS: 32 B - CPUS: 32
核心原因
两者的差异源于Java版本对容器CPU限制的感知逻辑变化:
- Java 8(早期版本)默认不识别Linux容器的cgroup CPU限制,直接读取宿主机的物理CPU总数,因此返回32。
- Java 11开始,HotSpot VM默认启用了
-XX:+UseContainerSupport参数,会自动识别容器的CPU配额(比如集群中给你的容器分配了1核CPU),此时availableProcessors()会返回容器的限制值而非宿主机物理CPU数,所以显示1。
验证与解决
如果想让Java 11回到Java 8的行为,忽略容器限制,只需在启动时添加JVM参数:
java -XX:-UseContainerSupport Test
此时程序会返回宿主机的32核CPU数量,与nproc结果一致。
内容的提问来源于stack exchange,提问作者Pierre
相关产品推荐
相关产品推荐

