Does Java's ActiveProcessorCount limit the number of CPUs the JVM can use?
Asked Answered
P

2

9

I'm using Oracle's Java 1.8.0_231.

What is the effect of setting -XX:ActiveProcessorCount=n? I'm not a C++ guy, but I think I see in the HotSpot source code these two uses:

  • Influence the number of HotSpot compiler threads
  • Influence the number of GC threads

However, does it actually limit the number of CPUs that the JVM can use? The Java 10 release notes plainly say:

In addition, this change adds a JVM option that provides the ability to specify the number of CPUs that the JVM will use.

My concern is that I have test results (outside of any Docker, CF, etc container) that seem to show the app using all 8 CPUs equally instead of the 4 I had set: All 8 CPUs

So, should setting ActiveProcessorCount actually limit the number of CPUs the JVM uses? I don't see anything in the HotSpot code that does that and my test results seem to also say no.

thanks

Potation answered 23/1, 2020 at 15:54 Comment(0)
H
8

To supplement the other answer by Mena and to prove out Kayaman's comment, the direct effect of this parameter is to set the value returned by Runtime.getRuntime().availableProcessors().

To prove this, I created a class

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

I then compiled and ran it using Java 11 on a 12-core machine with some different options:

# 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

This also worked on the latest version of Java 8, specifically OpenJDK 1.8.0_242-b08.

As already noted, this helps size thread pools but does not impose any hard limit on the number of CPU cores that can be used.

Hellenistic answered 20/4, 2020 at 17:0 Comment(0)
G
7

Not an expert, but interpreting the docs as plain English:

Overrides the number of CPUs that the VM will use to calculate the size of thread pools it will use for various operations such as Garbage Collection and ForkJoinPool.

This tells me it's not meant to limit core usage at runtime, but rather, well, "to calculate the size of thread pools [...]".

So it would follow that if you parametrize with half of your available CPUs, your thread pools for those JVM tasks will be smaller, but that would not impact the CPU utilization of your application as a whole at runtime.

Notes:

  1. The only version of the docs I found is for Java 11, so whether this has radically changed between v. 8, 10 and 11 might be open to interpretation (read: I have no clue).
  2. Moreover, the java 10 release notes you mention to suggest to me that the option may not be available at all in Java 8, hence taking no effect.
Gulledge answered 23/1, 2020 at 16:3 Comment(3)
Maybe it just affects Runtime.getRuntime().availableProcessors(); which is often used for all kinds of pool sizing and other such calculations.Blubber
@Blubber seems the method is used in the org.graalvm package too, on top of many concurrent classes.Gulledge
If you want to limit which CPUs a Java program runs on, you'll need to use an operating-system specific mechanism, such as 'taskset` on Linux.Vaporish

© 2022 - 2024 — McMap. All rights reserved.