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

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

我希望在不使用JNI的情况下获得这些信息。


当前回答

嘿,你可以通过java/com集成来做到这一点。通过访问WMI功能,您可以获得所有信息。

其他回答

您可以从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());
    }
  }
}

java.lang.management包确实比运行时提供了更多的信息——例如,它会将堆内存(ManagementFactory.getMemoryMXBean(). getheapmemoryusage())与非堆内存(ManagementFactory.getMemoryMXBean(). getnonheapmemoryusage())分开。

您还可以获得进程CPU使用情况(无需编写自己的JNI代码),但是您需要将java.lang.management.OperatingSystemMXBean转换为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();
        }
    }
}

我认为最好的方法是通过Hyperic实现SIGAR API。它适用于大多数主要的操作系统(几乎所有现代的操作系统),并且非常容易使用。开发者在他们的论坛和邮件列表上的反应非常积极。我还喜欢它是GPL2 Apache授权的。他们也提供了大量的Java示例!

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

有一个使用JNA(因此不需要安装本机库)的Java项目正在积极开发中。它目前支持Linux, OSX, Windows, Solaris和FreeBSD,并提供RAM, CPU,电池和文件系统信息。

https://github.com/oshi/oshi

看一下java.lang.management包中可用的api。例如:

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

还有很多其他有用的东西。