服务器测评网
我们一直在努力

Java如何获取CPU使用率及核心状态信息?

获取CPU状态的核心思路

在Java中获取CPU状态,本质上是通过操作系统提供的工具或接口,读取与CPU相关的性能指标,由于Java本身运行在Java虚拟机(JVM)之上,无法直接访问操作系统底层资源,因此需要借助第三方库或调用系统命令来实现,常见的CPU状态指标包括:CPU使用率、核心数、负载、进程CPU占用等,获取这些指标的方法主要有三种:通过系统命令解析、使用操作系统原生API(如JNA/JNR)、借助第三方监控工具(如Micrometer)。

Java如何获取CPU使用率及核心状态信息?

通过系统命令获取CPU状态

Linux/Unix系统

在Linux/Unix系统中,可以通过读取/proc/stat文件或调用topvmstat等命令获取CPU状态,以下是具体实现方式:

  • 读取/proc/stat文件
    该文件包含了CPU的详细统计信息,第一行以cpu开头,后续字段依次为:用户态时间、低优先级用户态时间、内核态时间、空闲时间、I/O等待时间、硬件中断时间、软件中断时间、虚拟机时间等。

    示例代码:

    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    public class CpuStatusViaProc {
        public static void main(String[] args) {
            try (BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"))) {
                String line = reader.readLine();
                if (line != null && line.startsWith("cpu ")) {
                    String[] parts = line.split("\\s+");
                    long user = Long.parseLong(parts[1]);
                    long nice = Long.parseLong(parts[2]);
                    long system = Long.parseLong(parts[3]);
                    long idle = Long.parseLong(parts[4]);
                    long total = user + nice + system + idle;
                    double usage = (double) (total - idle) / total * 100;
                    System.out.printf("CPU Usage: %.2f%%\n", usage);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • 调用topvmstat命令
    可以通过Runtime.exec()执行命令并解析输出结果,执行top -b -n 1 | grep "Cpu(s)"可获取CPU使用率。

    示例代码:

    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    public class CpuStatusViaCommand {
        public static void main(String[] args) {
            try {
                Process process = Runtime.getRuntime().exec("top -b -n 1 | grep \"Cpu(s)\"");
                BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                String line = reader.readLine();
                if (line != null) {
                    String[] parts = line.split(",");
                    String cpuUsage = parts[0].split("\\s+")[2].replace("%id", "");
                    System.out.printf("CPU Idle: %s%%\n", cpuUsage);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

Windows系统

Windows系统可以通过wmic命令或typeperf工具获取CPU状态,执行wmic cpu get loadpercentage可获取CPU使用率。

Java如何获取CPU使用率及核心状态信息?

示例代码:

  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  public class CpuStatusWindows {
      public static void main(String[] args) {
          try {
              Process process = Runtime.getRuntime().exec("wmic cpu get loadpercentage");
              BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
              reader.readLine(); // 跳过标题行
              String line = reader.readLine().trim();
              System.out.println("CPU Usage: " + line + "%");
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  }

使用JNA/JNR调用操作系统原生API

系统命令解析方式存在性能开销和跨平台兼容性问题,而JNA(Java Native Access)和JNR(Java Native Runtime)可以直接调用操作系统原生API,效率更高。

通过JNA获取CPU状态

以Linux系统为例,可以调用libproc库的函数读取/proc/stat,或使用sysinfo获取系统负载。

示例依赖(Maven):

  <dependency>
      <groupId>net.java.dev.jna</groupId>
      <artifactId>jna-platform</artifactId>
      <version>5.12.1</version>
  </dependency>

示例代码:

  import com.sun.jna.Library;
  import com.sun.jna.Native;
import com.sun.jna.Platform;
public interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary) Native.loadLibrary("c", CLibrary.class);
    int sysinfo(com.sun.jna.platform.linux.Sysinfo info);
}
public class CpuStatusJNA {
    public static void main(String[] args) {
        com.sun.jna.platform.linux.Sysinfo info = new com.sun.jna.platform.linux.Sysinfo();
        CLibrary.INSTANCE.sysinfo(info);
        System.out.println("CPU Load: " + info.loads[0] / 65536.0 + "%");
    }
}

通过JNR获取CPU状态

JNR是JNA的替代方案,性能更优,支持更多语言绑定,使用JNR-FFI调用getloadavg函数。

Java如何获取CPU使用率及核心状态信息?

示例依赖(Maven):

  <dependency>
      <groupId>com.github.jnr</groupId>
      <artifactId>jnr-ffi</artifactId>
      <version>2.2.13</version>
  </dependency>

示例代码:

  import jnr.ffi.LibraryLoader;
import jnr.ffi.Runtime;
public class CpuStatusJNR {
    public interface LibC {
        double[] getloadavg(double[] loadavg, int nelem);
    }
    public static void main(String[] args) {
        LibC libc = LibraryLoader.create(LibC.class).load("c");
        double[] loadavg = new double[1];
        libc.getloadavg(loadavg, 1);
        System.out.println("System Load Average: " + loadavg[0]);
    }
}

借助第三方监控工具(Micrometer)

对于生产环境,推荐使用成熟的监控工具如Micrometer,它提供了跨平台的指标收集能力,并支持与Prometheus、Grafana等系统集成。

添加依赖

<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-core</artifactId>
    <version>1.10.13</version>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
    <version>1.10.13</version>
</dependency>

示例代码

import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.binder.system.ProcessorMetrics;
import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
public class CpuStatusMicrometer {
    public static void main(String[] args) {
        PrometheusMeterRegistry registry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
        Metrics.addRegistry(registry);
        new ProcessorMetrics().bindTo(registry);
        System.out.println("CPU Metrics: " + registry.scrape());
    }
}

注意事项

  1. 跨平台兼容性:不同操作系统的CPU状态获取方式不同,需针对目标平台选择合适的方法。
  2. 性能影响:频繁调用系统命令或解析文件可能影响应用性能,建议缓存结果或使用异步方式。
  3. 权限问题:读取/proc/stat或执行系统命令可能需要root权限(Linux)或管理员权限(Windows)。
  4. JVM监控:Java应用还需关注JVM自身的CPU占用,可通过ManagementFactory.getOperatingSystemMXBean()获取JVM进程的CPU使用情况。

Java获取CPU状态的方法多样,从简单的系统命令解析到高效的JNA/JNR调用,再到成熟的监控工具集成,可根据实际需求选择,对于简单场景,系统命令解析足够;对于高性能或生产环境,推荐使用JNA/JNR或Micrometer,兼顾效率和可维护性,无论采用哪种方式,都需注意跨平台兼容性和性能开销,确保应用的稳定运行。

赞(0)
未经允许不得转载:好主机测评网 » Java如何获取CPU使用率及核心状态信息?