Finding Number of Cores in Java
Asked Answered
P

5

486

How can I find the number of cores available to my application from within Java code?

Pathognomy answered 21/1, 2011 at 13:54 Comment(4)
For pretty much all intents and purpose "core == processor".Untaught
finding the number of cores the machine has physically is hard using purely Java. Finding the number of cores the Java program can use at startup is easy, using Runtime.getRuntime().availableProcessors(). Due to the ability of all major modern OSes to set CPU affinity (i.e. restrict an application to only a certain number of cores) this is a concern to keep in mind.Contingence
Logical or physical cores? There's an important difference.Gwinn
Also see: #1981332Metts
D
882
int cores = Runtime.getRuntime().availableProcessors();

If cores is less than one, either your processor is about to die, or your JVM has a serious bug in it, or the universe is about to blow up.

Disregard answered 21/1, 2011 at 13:58 Comment(16)
No problem, since most of the information gathered from the Runtime class is a String, I thought it would be helpful to show this one returns an int.Conserve
This will give you the number of logical threads. e.g. If you have hyper-threading on, this will be double the number of cores.Boutin
@Peter, yeah, good point. I felt myself King of the Hill when performing this action with my i7 machine! :)Conserve
@Peter Lawrey: it only gives the number of logical threads actually available to the JVM (at startup I guess). Using CPU affinity the user/OS can restrict the number of "cores" a JVM sees. You can even do it on a running JVM but I'm not too sure how this influence availableProcessors().Contingence
@Contingence I suspect availableProcessors doesn't change with the affinity.Boutin
@PeterLawrey: that seems to be incorrect, the Java documentation for availableProcessors() says "This value may change during a particular invocation of the virtual machine. Applications that are sensitive to the number of available processors should therefore occasionally poll this property and adjust their resource usage appropriately." sourceCoumarin
@JW You could be right, I have never seen someone change the number of virtual CPUs of a running production system before. ;) I tend to only work in real machines which don't change.Boutin
@universe blowing up and such : or the machine actually has more than 2,147,483,647 logical threads available ? ;)Astronomical
@PierreHenry Well, that would be the day that we could solve all NP problems in P time for N <= 2 147 483 647 :)Lorgnon
@PeterLawrey There are real machines with hot swappable CPUs.Crampton
@PeterLawrey, I can confirm that on Windows 7 SP1 x64 with Java 1.7.0_51, availableProcessors() does change with the affinity. You can easily test this by using jrunscript to call java.lang.Runtime.getRuntime().availableProcessors(), change the processor affinity of jrunscript.exe with Windows task manager, and then run availableProcessors() again, you will see the number will change.Mccown
@PeterLawrey Real machines can gain or lose CPUs as well. I've hot-swapped processors (and RAM) on high-end servers with my own two hands.Gwinn
I have a lot of questions to all of you people running software straight on server hardware, rather than in a virtual machine.Peeler
Upvoted for being useful as well as having a sense of humourCathartic
@Peeler I have allot of questions for all you people who can see into the future so clearlyCircumscription
@dancarter even at the time it was the norm to use virtual machines to separate everything out.Peeler
C
37

If you want to get number of physical cores you can run cmd and terminal command and then to parse the output to get info you need.Below is shown function that returns number of physical cores .

private int getNumberOfCPUCores() {
    OSValidator osValidator = new OSValidator();
    String command = "";
    if(osValidator.isMac()){
        command = "sysctl -n machdep.cpu.core_count";
    }else if(osValidator.isUnix()){
        command = "lscpu";
    }else if(osValidator.isWindows()){
        command = "cmd /C WMIC CPU Get /Format:List";
    }
    Process process = null;
    int numberOfCores = 0;
    int sockets = 0;
    try {
        if(osValidator.isMac()){
            String[] cmd = { "/bin/sh", "-c", command};
            process = Runtime.getRuntime().exec(cmd);
        }else{
            process = Runtime.getRuntime().exec(command);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

    BufferedReader reader = new BufferedReader(
            new InputStreamReader(process.getInputStream()));
    String line;

    try {
        while ((line = reader.readLine()) != null) {
            if(osValidator.isMac()){
                numberOfCores = line.length() > 0 ? Integer.parseInt(line) : 0;
            }else if (osValidator.isUnix()) {
                if (line.contains("Core(s) per socket:")) {
                    numberOfCores = Integer.parseInt(line.split("\\s+")[line.split("\\s+").length - 1]);
                }
                if(line.contains("Socket(s):")){
                    sockets = Integer.parseInt(line.split("\\s+")[line.split("\\s+").length - 1]);
                }
            } else if (osValidator.isWindows()) {
                if (line.contains("NumberOfCores")) {
                    numberOfCores = Integer.parseInt(line.split("=")[1]);
                }
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    if(osValidator.isUnix()){
        return numberOfCores * sockets;
    }
    return numberOfCores;
}

OSValidator class:

public class OSValidator {

private static String OS = System.getProperty("os.name").toLowerCase();

public static void main(String[] args) {

    System.out.println(OS);

    if (isWindows()) {
        System.out.println("This is Windows");
    } else if (isMac()) {
        System.out.println("This is Mac");
    } else if (isUnix()) {
        System.out.println("This is Unix or Linux");
    } else if (isSolaris()) {
        System.out.println("This is Solaris");
    } else {
        System.out.println("Your OS is not support!!");
    }
}

public static boolean isWindows() {
    return (OS.contains("win"));
}

public static boolean isMac() {
    return (OS.contains("mac"));
}

public static boolean isUnix() {
    return (OS.contains("nix") || OS.contains("nux") || OS.contains("aix") );
}

public static boolean isSolaris() {
    return (OS.contains("sunos"));
}
public static String getOS(){
    if (isWindows()) {
        return "win";
    } else if (isMac()) {
        return "osx";
    } else if (isUnix()) {
        return "uni";
    } else if (isSolaris()) {
        return "sol";
    } else {
        return "err";
    }
}

}

Constrictive answered 30/12, 2015 at 8:28 Comment(4)
This is a piece of code that is a good candidate to be OOPed. :)Kessel
The OSValidator class supports OSX, but the getNumberOfCores completely ignores it. As an aside, blog.opengroup.org/2015/10/02/… so 'Mac' should be in your isUnix() but... For BSD, OSX, no lscpu command exists and your getNumberOfCores will return 0.Dehnel
On Linux, you have to multiple "Core(s) per socket" by "Socket(s)". Also, I would use regular expressions.Clothespress
Its better to use "OS.contains()" instead of "OS.indexOf()". It improves readability and is less to type.Castorina
C
14

This is an additional way to find out the number of CPU cores (and a lot of other information), but this code requires an additional dependence:

Native Operating System and Hardware Information https://github.com/oshi/oshi

SystemInfo systemInfo = new SystemInfo();
HardwareAbstractionLayer hardwareAbstractionLayer = systemInfo.getHardware();
CentralProcessor centralProcessor = hardwareAbstractionLayer.getProcessor();

Get the number of logical CPUs available for processing:

centralProcessor.getLogicalProcessorCount();
Clerc answered 3/10, 2018 at 14:20 Comment(1)
This will also let you use centralProcessor.getPhysicalProcessorCount(), which is probably currently the best way in java to obtain that information. If you have threads which almost constantly have work to do, and you want to know the number of such threads you can start while still leaving a well-defined leftover of CPU capacity for other threads and processes, this is the number the calculation should be based on.Sherrard
H
1

If you want to dubbel check the amount of cores you have on your machine to the number your java program is giving you.

In Linux terminal: lscpu

In Windows terminal (cmd): echo %NUMBER_OF_PROCESSORS%

In Mac terminal: sysctl -n hw.ncpu

Hampstead answered 20/10, 2020 at 14:7 Comment(1)
%NUMBER_OF_PROCESSORS% outputs number of logical coresMickeymicki
M
-7

This works on Windows with Cygwin installed:

System.getenv("NUMBER_OF_PROCESSORS")

Mcwhorter answered 18/10, 2013 at 21:12 Comment(2)
I have Cygwin installed, but this works from the Windows shell: groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"Gladiate
I don't know off the top of my head if this is a standard Windows environment variable, but: set NUMBER_OF_PROCESSORS works from the Windows command line for me.Gladiate

© 2022 - 2024 — McMap. All rights reserved.