获取操作系统级别的系统信息

Ste*_*e M 230 java memory resources system

我目前正在构建一个Java应用程序,最终可能会在许多不同的平台上运行,但主要是Solaris,Linux和Windows的变种.

有没有人能够成功提取信息,例如当前使用的磁盘空间,CPU利用率和底层操作系统中使用的内存?那么Java应用程序本身正在消耗什么呢?

我更希望在不使用JNI的情况下获取此信息.

Wil*_*del 202

您可以从Runtime类中获取一些有限的内存信息.这真的不是你想要的,但我想我会为了完整而提供它.这是一个小例子.编辑:您还可以从java.io.File类获取磁盘使用信息.磁盘空间使用情况需要Java 1.6或更高版本.

public class Main {
  public static void main(String[] args) {
    /* Total number of processors or cores available to the JVM */
    System.out.println("Available processors (cores): " + 
        Runtime.getRuntime().availableProcessors());

    /* Total amount of free memory available to the JVM */
    System.out.println("Free memory (bytes): " + 
        Runtime.getRuntime().freeMemory());

    /* This will return Long.MAX_VALUE if there is no preset limit */
    long maxMemory = Runtime.getRuntime().maxMemory();
    /* Maximum amount of memory the JVM will attempt to use */
    System.out.println("Maximum memory (bytes): " + 
        (maxMemory == Long.MAX_VALUE ? "no limit" : maxMemory));

    /* Total memory currently available to the JVM */
    System.out.println("Total memory available to JVM (bytes): " + 
        Runtime.getRuntime().totalMemory());

    /* Get a list of all filesystem roots on this system */
    File[] roots = File.listRoots();

    /* For each filesystem root, print some info */
    for (File root : roots) {
      System.out.println("File system root: " + root.getAbsolutePath());
      System.out.println("Total space (bytes): " + root.getTotalSpace());
      System.out.println("Free space (bytes): " + root.getFreeSpace());
      System.out.println("Usable space (bytes): " + root.getUsableSpace());
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 这不能正确回答问题.所有这些数据都转发给JVM而不是操作系统...... (12认同)
  • 我认为"JVM当前使用的总内存"有点令人困惑.[javadoc](http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html#totalMemory%28%29)表示该函数返回"当前可用于的总内存量"当前和未来的对象,以字节为单位." 听起来更像是剩余的内存而没有使用. (6认同)

Pat*_*kes 93

java.lang.management包确实给你比运行了一大堆更多信息-例如,它会给你堆内存(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage())从非堆内存分开(ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()).

您还可以获得进程CPU使用率(无需编写自己的JNI代码),但需要将其转换java.lang.management.OperatingSystemMXBean为a com.sun.management.OperatingSystemMXBean.这适用于Windows和Linux,我没有在其他地方测试过.

例如...更频繁地调用get getCpuUsage()方法以获得更准确的读数.

public class PerformanceMonitor { 
    private int  availableProcessors = getOperatingSystemMXBean().getAvailableProcessors();
    private long lastSystemTime      = 0;
    private long lastProcessCpuTime  = 0;

    public synchronized double getCpuUsage()
    {
        if ( lastSystemTime == 0 )
        {
            baselineCounters();
            return;
        }

        long systemTime     = System.nanoTime();
        long processCpuTime = 0;

        if ( getOperatingSystemMXBean() instanceof OperatingSystemMXBean )
        {
            processCpuTime = ( (OperatingSystemMXBean) getOperatingSystemMXBean() ).getProcessCpuTime();
        }

        double cpuUsage = (double) ( processCpuTime - lastProcessCpuTime ) / ( systemTime - lastSystemTime );

        lastSystemTime     = systemTime;
        lastProcessCpuTime = processCpuTime;

        return cpuUsage / availableProcessors;
    }

    private void baselineCounters()
    {
        lastSystemTime = System.nanoTime();

        if ( getOperatingSystemMXBean() instanceof OperatingSystemMXBean )
        {
            lastProcessCpuTime = ( (OperatingSystemMXBean) getOperatingSystemMXBean() ).getProcessCpuTime();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 要使它编译,将强制转换的`OperatingSystemMXBean`替换为`com.sun.management.OperatingSystemMXBean`,并将`getOperatingSystemMXBean()`的所有实例添加到`ManagementFactory.您需要适当地导入所有类. (10认同)
  • 我的cpu使用率为0.我将cpu使用公式更改为cpuUsage = processCpuTime/systemTime.我得到了cpu使用的值,我不明白. (2认同)
  • 我总是得到0,因为@Raj说...你能举例说明如何使用该代码吗? (2认同)

Mat*_*ngs 42

我认为最好的方法是通过Hyperic实现SIGAR API.它适用于大多数主要操作系统(靠近任何现代设备)并且非常容易使用.开发人员对他们的论坛和邮件列表非常敏感.我也喜欢它是GPL2 Apache许可.它们也提供了大量的Java示例!

SIGAR ==系统信息,收集和报告工具.

  • Sigar自2010年以来没有更新,似乎在64位系统上有一个错误:http://stackoverflow.com/questions/23405832/sigar-1-6-4-is-useless-exception-access-violation (8认同)
  • @Yohan - 别偷!您可以通过*阅读*链接的网页找到它.(这取决于"平台独立"的含义.) (2认同)
  • @StephenC:Sigar使用的是.dll文件,这使其依赖于平台。更高级别的API可能是Java语言,情况有所不同 (2认同)
  • 并且 SIGAR 也会使 JVM 崩溃(虽然是间歇性的),但我相信您不会在生产中冒这个风险。 (2认同)

dB.*_*dB. 23

有使用JNA(所以没有机库安装),并正在积极开发的Java项目.它目前支持Linux,OSX,Windows,Solaris和FreeBSD和提供RAM,CPU,电池和文件系统信息.

  • @rhb - 我不相信。当我用谷歌搜索“jvm crash libffi”时,我看到很多点击。 (2认同)

Yan*_*ski 12

对于Windows我走了这条路.

    com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();

    long physicalMemorySize = os.getTotalPhysicalMemorySize();
    long freePhysicalMemory = os.getFreePhysicalMemorySize();
    long freeSwapSize = os.getFreeSwapSpaceSize();
    long commitedVirtualMemorySize = os.getCommittedVirtualMemorySize();
Run Code Online (Sandbox Code Playgroud)

这是与细节的链接.


Ale*_*ndr 11

您可以通过使用System.getenv()相关环境变量名称作为参数来获取一些系统级信息.例如,在Windows上:

System.getenv("PROCESSOR_IDENTIFIER")
System.getenv("PROCESSOR_ARCHITECTURE")
System.getenv("PROCESSOR_ARCHITEW6432")
System.getenv("NUMBER_OF_PROCESSORS")
Run Code Online (Sandbox Code Playgroud)

对于其他操作系统,相关环境变量的存在/不存在和名称将有所不同.


Ole*_*syn 7

通过maven添加OSHI依赖:

<dependency>
    <groupId>com.github.dblock</groupId>
    <artifactId>oshi-core</artifactId>
    <version>2.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

获得剩余百分比的电池容量:

SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
for (PowerSource pSource : hal.getPowerSources()) {
    System.out.println(String.format("%n %s @ %.1f%%", pSource.getName(), pSource.getRemainingCapacity() * 100d));
}
Run Code Online (Sandbox Code Playgroud)


sta*_*fan 6

查看java.lang.management包中提供的API .例如:

  • OperatingSystemMXBean.getSystemLoadAverage()
  • ThreadMXBean.getCurrentThreadCpuTime()
  • ThreadMXBean.getCurrentThreadUserTime()

那里还有许多其他有用的东西.

  • 在Windows中没有实现OperatingSystemMXBean.getSystemLoadAverage(),因为"它太贵了" (2认同)

Pet*_*rey 5

通常,要获得低级别的操作系统信息,您可以调用操作系统特定的命令,这些命令可以为您提供Runtime.exec()所需的信息,或者在Linux中读取/ proc/*等文件.


Par*_*udy 5

CPU使用率并不简单 - 通过com.sun.management.OperatingSystemMXBean.getProcessCpuTime的java.lang.management接近(参见上面Patrick的优秀代码片段),但请注意,它只能访问CPU在您的进程中花费的时间.它不会告诉您在其他进程中花费的CPU时间,甚至不会告诉您执行与进程相关的系统活动所花费的CPU时间.

例如,我有一个网络密集型的java进程 - 它是唯一运行的东西,CPU是99%,但只有55%被报告为"处理器CPU".

尽管它是MX bean上唯一与cpu相关的项目,但它甚至没有让我开始"平均负载",因为它是无用的.如果只有太阳在偶尔的智慧中暴露出类似"getTotalCpuTime"的东西......

对于严重的CPU监控,Matt提到的SIGAR似乎是最好的选择.