在Java中查找内核数


411

如何从Java代码中找到可用于我的应用程序的内核数?


3
出于所有意图和目的,“核心==处理器”。
约阿希姆·绍尔

32
使用纯Java很难找到机器实际具有的内核数量。使用Runtime.getRuntime()。availableProcessors()可以很容易地找到Java程序在启动时可以使用的内核数。由于所有主要的现代OS都具有设置CPU亲和力的能力(即,将应用程序仅限制为一定数量的内核),因此需要牢记这一点。
SyntaxT3rr0r 2011年

6
逻辑或物理核心?有一个重要的区别。
b1nary.atr0phy

Answers:


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

如果cores小于1,则说明您的处理器即将死机,或者JVM中存在严重的错误,或者Universe即将崩溃。


106
这将为您提供逻辑线程的数量。例如,如果启用了超线程,这将是内核数量的两倍。
彼得·劳瑞

6
@Peter,是的,很好。在我的i7机器上执行此操作时,我感到自己是山丘之王!:)
Bart Kiers

14
@Peter Lawrey:它仅给出了JVM实际可用的逻辑线程数(我猜是在启动时)。使用CPU亲缘关系,用户/ OS可以限制JVM看到的“核心”数量。您甚至可以在运行的JVM上执行此操作,但我不太确定这会如何影响availableProcessors()
SyntaxT3rr0r 2011年

25
@PeterLawrey:这似乎是不正确的,availableProcessors()的Java文档说:“在虚拟机的特定调用期间,此值可能会更改。因此,对可用处理器数量敏感的应用程序应该偶尔轮询此属性并调整其属性。资源使用情况。” 来源
JW。

9
@universe爆炸等等:还是该机器实际上有超过2,147,483,647个逻辑线程可用?;)
皮埃尔·亨利

26

如果要获取物理核心数,可以运行cmd和terminal命令,然后解析输出以获取所需的信息。下面显示的函数返回物理核心数。

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
这是一段易于被OOP处理的代码。:)
Lyubomyr Shaydariv 2015年

1
OSValidator类支持OSX,但是getNumberOfCores完全忽略它。顺便说一句,blog.opengroup.org/2015/10/02/... 所以“苹果”应该是在你的isUnix(),但...对于BSD,OSX,没有lscpu命令存在,您getNumberOfCores将返回0
保罗Hargreaves

1
在Linux上,您必须将多个“每个套接字的核心”乘以“套接字”。另外,我会使用正则表达式。
Aleksandr Dubinsky

1
最好使用“ OS.contains()”而不是“ OS.indexOf()”。它提高了可读性,并且很少键入。
Josh Gager

6

这是找出CPU内核数量(以及许多其他信息)的另一种方法,但是此代码需要附加的依赖性:

本机操作系统和硬件信息 https://github.com/oshi/oshi

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

获取可用于处理的逻辑CPU的数量:

centralProcessor.getLogicalProcessorCount();

这也将允许您使用centralProcessor.getPhysicalProcessorCount(),这可能是当前Java中获取该信息的最佳方法。如果您的线程几乎总是需要做的工作,并且想知道可以启动的此类线程的数量,同时仍然为其他线程和进程保留明确定义的CPU容量剩余,则此数目应为计算值基于。
malamut

-3

在安装Cygwin的Windows上可以使用:

System.getenv("NUMBER_OF_PROCESSORS")


我已经安装了Cygwin,但是可以从Windows shell运行:groovy -e "println System.getenv('NUMBER_OF_PROCESSORS')"
AbuNassar

我不知道这是否是标准Windows环境变量,但是:set NUMBER_OF_PROCESSORS从Windows命令行对我来说有效。
AbuNassar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.