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?


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

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.


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

}


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

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")


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.