javaenvironment-variablescpu-coresprocessors

Windows environment variable NUMBER_OF_PROCESSORS shows different value within JVM and outside


On our Windows Server 2019, we have 36 cores and 72 logical processors, as seen in Task Manager CPU performance window. And, also, if from command prompt, if I run the command.

echo %NUMBER_OF_PROCESSORS%

It tells me 72.

However, from within Java program, if I run the following code snippet,

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);
    }
}

the output comes as:

NUMBER_OF_PROCESSORS (from env) = 36

Compiled with 64-bit Java 8 compiler on Windows in Netbeans IDE. Made an executable jar. Ran the jar, as:

java -jar NoOfCPUs.jar

Same system environment variable, NUMBER_OF_PROCESSORS is showing me different result from a command prompt vs from within Java program.

Why?

Is it because of logical processor group that Windows use after 2009 version? Logical processor group holds maximum of 64 processors in a group.


Solution

  • This seems related to other questions like these:

    and this bug report says it will not be supported (won't fix):

    https://bugs.openjdk.java.net/browse/JDK-6942632

    The bug report says that is should be the responsibility of the user to configure the right amount of CPU's to Java, this is possible with:

    1. https://bitsum.com/portfolio/groupextend/
    2. Possibly other ones because of affinity inheritance like start /affinity, see this answer but I cannot test/confirm because my laptop does not have that many cores

    I think you should consider running multiple instances of your application (and Java) instead of just one to gain maximum performance anyway because of NUMA locality, although different Java Virtual Machines have 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

    If the limit is specific to the HotSpotVM (originates from Sun/Oracle) you may want to take a look at a different Java Virtual Machine OpenJ9 (originates from IBM) and others like Azul Zing JVM

    If it is a Windows specific limit, you may want to consider switching to a different Operating System or running multiple instances of Windows through a hypervisor of your choice.