Encontrar el número de núcleos en Java

412

¿Cómo puedo encontrar la cantidad de núcleos disponibles para mi aplicación desde el código Java?

Damir
fuente
3
Para casi todos los intentos y propósitos "core == procesador".
Joachim Sauer
32
Encontrar el número de núcleos que la máquina tiene físicamente es difícil usando puramente Java. Encontrar la cantidad de núcleos que el programa Java puede usar al inicio es fácil, usando Runtime.getRuntime (). AvailableProcessors () . Debido a la capacidad de todos los sistemas operativos modernos más importantes para establecer la afinidad de la CPU (es decir, restringir una aplicación a solo un cierto número de núcleos), esta es una preocupación a tener en cuenta.
SyntaxT3rr0r
66
Núcleos lógicos o físicos? Hay una diferencia importante
b1nary.atr0phy
Ver también: stackoverflow.com/questions/1980832/…
Christophe Roussy el

Respuestas:

726
int cores = Runtime.getRuntime().availableProcessors();

Si coreses menos de uno, o su procesador está a punto de morir, o su JVM tiene un error grave, o el universo está a punto de explotar.

darioo
fuente
107
Esto le dará la cantidad de hilos lógicos. por ejemplo, si tiene hiperprocesamiento activado, esto duplicará el número de núcleos.
Peter Lawrey
66
@ Peter, sí, buen punto. ¡Me sentí rey de la colina al realizar esta acción con mi máquina i7! :)
Bart Kiers
14
@ Peter Lawrey: solo da la cantidad de hilos lógicos realmente disponibles para la JVM (supongo que al inicio). Usando la afinidad de la CPU, el usuario / SO puede restringir el número de "núcleos" que ve una JVM. Incluso puede hacerlo en una JVM en ejecución, pero no estoy muy seguro de cómo influye esto enProcesadores disponibles () .
SyntaxT3rr0r
25
@PeterLawrey: eso parece ser incorrecto, la documentación de Java para availableProcessors () dice "Este valor puede cambiar durante una invocación particular de la máquina virtual. Las aplicaciones que son sensibles a la cantidad de procesadores disponibles deben, por lo tanto, sondear ocasionalmente esta propiedad y ajustar su uso apropiado de los recursos ". fuente
JW.
99
@universe explota y tal: ¿o la máquina realmente tiene más de 2,147,483,647 hilos lógicos disponibles? ;)
Pierre Henry
26

Si desea obtener el número de núcleos físicos, puede ejecutar cmd y el comando de terminal y luego analizar el resultado para obtener la información que necesita. A continuación se muestra la función que devuelve el número de núcleos físicos.

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

Clase OSValidator:

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.indexOf("win") >= 0);
}

public static boolean isMac() {
    return (OS.indexOf("mac") >= 0);
}

public static boolean isUnix() {
    return (OS.indexOf("nix") >= 0 || OS.indexOf("nux") >= 0 || OS.indexOf("aix") > 0 );
}

public static boolean isSolaris() {
    return (OS.indexOf("sunos") >= 0);
}
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";
    }
}

}

adi9090
fuente
44
Este es un código que es un buen candidato para OOP. :)
Lyubomyr Shaydariv
1
La clase OSValidator es compatible con OSX, pero getNumberOfCores lo ignora por completo. Por otro lado, blog.opengroup.org/2015/10/02/… así que 'Mac' debería estar en su isUnix () pero ... Para BSD, OSX, no existe ningún comando lscpu y su getNumberOfCores devolverá 0.
Paul Hargreaves
1
En Linux, debe tener varios "Core (s) por socket" por "Socket (s)". Además, usaría expresiones regulares.
Aleksandr Dubinsky
1
Es mejor usar "OS.contains ()" en lugar de "OS.indexOf ()". Mejora la legibilidad y es menos de escribir.
Josh Gager
6

Esta es una forma adicional de averiguar la cantidad de núcleos de CPU (y mucha otra información), pero este código requiere una dependencia adicional:

Sistema operativo nativo e información de hardware https://github.com/oshi/oshi

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

Obtenga el número de CPU lógicas disponibles para procesar:

centralProcessor.getLogicalProcessorCount();
Antonio
fuente
Esto también le permitirá usar centralProcessor.getPhysicalProcessorCount (), que probablemente sea la mejor forma en Java de obtener esa información. Si tiene subprocesos que tienen trabajo que hacer casi constantemente, y desea saber la cantidad de subprocesos que puede iniciar sin dejar un resto de capacidad de CPU bien definido para otros subprocesos y procesos, este es el número que debe calcularse. Residencia en.
malamut
-3

Esto funciona en Windows con Cygwin instalado:

System.getenv("NUMBER_OF_PROCESSORS")

Lyle Z
fuente
Tengo instalado Cygwin, pero esto funciona desde el shell de Windows:groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"
AbuNassar
No sé de la cabeza si esta es una variable de entorno estándar de Windows, pero: set NUMBER_OF_PROCESSORSfunciona desde la línea de comandos de Windows para mí.
AbuNassar