Пошук кількості ядер на Java


411

Як я можу знайти кількість ядер, доступних моїй програмі, в коді Java?


3
Для майже всіх намірів і цілей "core == процесор".
Йоахім Зауер

32
знайти кількість ядер, якими машина є фізично, важко використовувати суто Java. Знайти кількість ядер, яку програма Java може використовувати при запуску, легко, використовуючи Runtime.getRuntime (). AvailableProcessors () . Завдяки можливості всіх основних сучасних ОС встановлювати спорідненість процесора (тобто обмежувати додаток лише певною кількістю ядер), про це слід пам'ятати.
SyntaxT3rr0r

6
Логічні чи фізичні ядра? Є важлива різниця.
b1nary.atr0phy

Відповіді:


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

Якщо coresменше одного, або ваш процесор ось-ось загине, або ваш JVM має серйозну помилку в ньому, або всесвіт ось-ось підірветься.


106
Це дасть вам кількість логічних потоків. Наприклад, якщо у вас гіпер-нарізка, це буде вдвічі більше ядер.
Пітер Лорі

6
@ Петер, так, хороший момент. Я відчував себе Королем Гірки, виконуючи цю дію зі своєю машиною i7! :)
Барт Кіерс

14
@ Петер Лоурі: він дає лише кількість логічних потоків, фактично доступних для JVM (при запуску я думаю). Використовуючи спорідненість до процесора, користувач / ОС можуть обмежувати кількість "ядер", які бачить JVM. Ви навіть можете це зробити на запущеному JVM, але я не надто впевнений, наскільки це впливаєProcessors () .
SyntaxT3rr0r

25
@PeterLawrey: що здається невірним, у документації Java для availableProcessors () написано: "Це значення може змінюватися під час певного виклику віртуальної машини. Програми, чутливі до кількості доступних процесорів, повинні періодично опитувати цю властивість та коригувати їх використання ресурсів належним чином. " джерело
JW.

9
@universe підірвання і таке: або в машині насправді доступно більше 2,147,483,647 логічних ниток? ;)
П’єр Генрі

26

Якщо ви хочете отримати кількість фізичних ядер, ви можете запустити команду cmd та термінал, а потім проаналізувати вихід, щоб отримати необхідну інформацію. Нижче показана функція, яка повертає кількість фізичних ядер.

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:

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

}


4
Це фрагмент коду, який є хорошим кандидатом на отримання OOPed. :)
Любомир Шайдарів

1
Клас OSValidator підтримує OSX, але getNumberOfCores повністю ігнорує його. На відміну від blog.opengroup.org/2015/10/02/…, тому "Mac" повинен бути у вашому isUnix (), але ... Для BSD, OSX, ніякої команди lscpu не існує, і ваш getNumberOfCores поверне 0.
Пол Hargreaves

1
В Linux ви повинні кілька "Core (s) per socket" на "Socket (s)". Також я б використовував регулярні вирази.
Олександр Дубінський

1
Краще використовувати "OS.contains ()" замість "OS.indexOf ()". Він покращує читабельність і менш вводить текст.
Джош Гагер

6

Це додатковий спосіб дізнатися кількість ядер процесора (та багато іншої інформації), але цей код вимагає додаткової залежності:

Інформація про рідну операційну систему та обладнання: https://github.com/oshi/oshi

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

Отримайте кількість логічних процесорів, доступних для обробки:

centralProcessor.getLogicalProcessorCount();

Це також дозволить вам використовувати centralProcessor.getPhysicalProcessorCount (), який, мабуть, є найкращим способом в Java для отримання цієї інформації. Якщо у вас є потоки, які майже постійно мають бути виконані, і ви хочете знати кількість таких потоків, яку можна починати, залишаючи чітко визначений залишок ємності процесора для інших потоків і процесів, це число, яке має бути розрахунком на основі.
маламут

-3

Це працює в Windows із встановленим Cygwin:

System.getenv("NUMBER_OF_PROCESSORS")


У мене встановлений Cygwin, але це працює з оболонки Windows:groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"
AbuNassar

Я не знаю вгорі голови, чи це стандартна змінна середовище Windows, але: set NUMBER_OF_PROCESSORSпрацює для мене командний рядок Windows.
AbuNassar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.