Ermitteln der Anzahl der Kerne in Java

411

Wie kann ich die Anzahl der für meine Anwendung verfügbaren Kerne in Java-Code ermitteln?

Damir
quelle
3
Für so ziemlich alle Absichten und Zwecke "core == processor".
Joachim Sauer
32
Mit rein Java ist es schwierig, die Anzahl der Kerne zu ermitteln, über die der Computer physisch verfügt. Mit Runtime.getRuntime (). AvailableProcessors () ist es einfach, die Anzahl der Kerne zu ermitteln, die das Java-Programm beim Start verwenden kann . Aufgrund der Fähigkeit aller großen modernen Betriebssysteme, die CPU-Affinität festzulegen (dh eine Anwendung auf nur eine bestimmte Anzahl von Kernen zu beschränken), ist dies ein zu beachtendes Anliegen.
SyntaxT3rr0r
6
Logische oder physische Kerne? Es gibt einen wichtigen Unterschied.
b1nary.atr0phy
Siehe auch: stackoverflow.com/questions/1980832/…
Christophe Roussy

Antworten:

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

Wenn coreses weniger als eins ist, ist entweder Ihr Prozessor im Begriff zu sterben, oder Ihre JVM hat einen schwerwiegenden Fehler, oder das Universum steht kurz vor der Explosion.

Darioo
quelle
106
Dadurch erhalten Sie die Anzahl der logischen Threads. Wenn Sie beispielsweise Hyper-Threading aktiviert haben, ist dies die doppelte Anzahl von Kernen.
Peter Lawrey
6
@ Peter, ja, guter Punkt. Ich fühlte mich als König des Hügels, als ich diese Aktion mit meiner i7-Maschine ausführte! :)
Bart Kiers
14
@ Peter Lawrey: Es gibt nur die Anzahl der logischen Threads an, die der JVM tatsächlich zur Verfügung stehen (beim Start, denke ich). Mit der CPU-Affinität kann der Benutzer / das Betriebssystem die Anzahl der "Kerne" einschränken, die eine JVM sieht. Sie können dies sogar auf einer laufenden JVM tun, aber ich bin mir nicht sicher, wie sich dies auf die verfügbaren Prozessoren () auswirkt .
SyntaxT3rr0r
25
@PeterLawrey: Das scheint falsch zu sein. In der Java-Dokumentation für availableProcessors () heißt es: "Dieser Wert kann sich während eines bestimmten Aufrufs der virtuellen Maschine ändern. Anwendungen, die auf die Anzahl der verfügbaren Prozessoren reagieren, sollten daher gelegentlich diese Eigenschaft abfragen und ihre anpassen Ressourcennutzung angemessen. " Quelle
JW.
9
@universe explodiert und so: oder hat die Maschine tatsächlich mehr als 2.147.483.647 logische Threads zur Verfügung? ;)
Pierre Henry
26

Wenn Sie die Anzahl der physischen Kerne abrufen möchten, können Sie den Befehl cmd und terminal ausführen und dann die Ausgabe analysieren, um die benötigten Informationen abzurufen. Die folgende Funktion zeigt die Anzahl der physischen Kerne an.

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-Klasse:

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
quelle
4
Dies ist ein Stück Code, der ein guter Kandidat für die OOP ist. :)
Lyubomyr Shaydariv
1
Die OSValidator-Klasse unterstützt OSX, aber getNumberOfCores ignoriert dies vollständig. Nebenbei bemerkt , blog.opengroup.org/2015/10/02/… also sollte 'Mac' in Ihrem isUnix () sein, aber ... Für BSD, OSX existiert kein lscpu-Befehl und Ihr getNumberOfCores gibt 0.
Paul zurück Hargreaves
1
Unter Linux müssen Sie "Core (s) per Socket" mit "Socket (s)" multiplizieren. Außerdem würde ich reguläre Ausdrücke verwenden.
Aleksandr Dubinsky
1
Es ist besser, "OS.contains ()" anstelle von "OS.indexOf ()" zu verwenden. Es verbessert die Lesbarkeit und ist weniger zu tippen.
Josh Gager
6

Dies ist eine zusätzliche Möglichkeit, die Anzahl der CPU-Kerne (und viele andere Informationen) herauszufinden. Dieser Code erfordert jedoch eine zusätzliche Abhängigkeit:

Native Betriebssystem- und Hardwareinformationen https://github.com/oshi/oshi

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

Ermitteln Sie die Anzahl der für die Verarbeitung verfügbaren logischen CPUs:

centralProcessor.getLogicalProcessorCount();
Antonio
quelle
Auf diese Weise können Sie auch centralProcessor.getPhysicalProcessorCount () verwenden. Dies ist derzeit wahrscheinlich der beste Weg, um diese Informationen in Java abzurufen. Wenn Sie Threads haben, die fast ständig Arbeit zu erledigen haben, und Sie die Anzahl solcher Threads wissen möchten, die Sie starten können, während für andere Threads und Prozesse noch ein genau definierter Rest der CPU-Kapazität übrig bleibt, sollte diese Zahl berechnet werden beyogen auf.
Malamut
-3

Dies funktioniert unter Windows mit installiertem Cygwin:

System.getenv("NUMBER_OF_PROCESSORS")

Lyle Z.
quelle
Ich habe Cygwin installiert, aber dies funktioniert über die Windows-Shell:groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"
AbuNassar
Ich weiß nicht genau, ob dies eine Standard-Windows-Umgebungsvariable ist, aber: set NUMBER_OF_PROCESSORSfunktioniert für mich über die Windows-Befehlszeile.
AbuNassar