Нахождение количества ядер в Java


412

Как узнать количество ядер, доступных для моего приложения, из кода Java?


3
Для почти всех намерений и целей "core == процессор".
Иоахим Зауэр

32
найти количество ядер, которые физически имеет машина, сложно, используя только Java. Найти количество ядер, которые Java-программа может использовать при запуске, легко, используя Runtime.getRuntime (). AvailableProcessors () . Из-за способности всех основных современных ОС устанавливать привязку к процессору (то есть ограничивать приложение только определенным числом ядер), об этом следует помнить.
СинтаксисT3rr0r

6
Логические или физические ядра? Есть важное отличие.
b1nary.atr0phy

Ответы:


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

Если значение coresменьше единицы, ваш процессор собирается умереть, или у вашей JVM есть серьезная ошибка, или вселенная собирается взорваться.


107
Это даст вам количество логических потоков. Например, если у вас включена гиперпоточность, количество ядер будет удвоено.
Питер Лори

6
@ Питер, да, хорошая мысль. Я чувствовал себя королем горы, когда выполнял это действие с моей машиной i7! :)
Барт Киерс

14
@Peter Lawrey: он дает только количество логических потоков, фактически доступных для JVM (я думаю, при запуске). Используя привязку к процессору, пользователь / ОС может ограничить количество «ядер», которые видит JVM. Вы даже можете сделать это на работающей JVM, но я не слишком уверен, как это влияет на availableProcessors () .
СинтаксисT3rr0r

25
@PeterLawrey: это кажется неправильным, в документации Java для availableProcessors () говорится: «Это значение может изменяться во время определенного вызова виртуальной машины. Поэтому приложения, чувствительные к числу доступных процессоров, должны периодически опрашивать это свойство и корректировать их. использование ресурсов надлежащим образом. " Источник
JW.

9
@ Вселенная взорвалась и все такое: или на самом деле на машине доступно более 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/…, поэтому в вашем isUnix () должно быть указано «Mac», но ... Для BSD, OSX, команда lscpu не существует, и ваш getNumberOfCores вернет 0.
Пол Харгривз

1
В Linux вам нужно несколько «Core (s) на сокет» на «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.