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

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

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


当前回答

不是你想要的,但是我建议你从common -lang3中查看ArchUtils和SystemUtils。它们还包含一些相关的辅助工具,例如:

import static org.apache.commons.lang3.ArchUtils.*;
import static org.apache.commons.lang3.SystemUtils.*;

System.out.printf("OS architecture: %s\n", OS_ARCH); // OS architecture: amd64
System.out.printf("OS name: %s\n", OS_NAME);         // OS name: Linux
System.out.printf("OS version: %s\n", OS_VERSION);   // OS version: 5.18.16-200.fc36.x86_64

System.out.printf("Is Linux? - %b\n", IS_OS_LINUX);     // Is Linux? - true
System.out.printf("Is Mac? - %b\n", IS_OS_MAC);         // Is Mac? - false
System.out.printf("Is Windows? - %b\n", IS_OS_WINDOWS); // Is Windows? - false

System.out.printf("JVM name: %s\n", JAVA_VM_NAME);       // JVM name: Java HotSpot(TM) 64-Bit Server VM
System.out.printf("JVM vendor: %s\n", JAVA_VM_VENDOR);   // JVM vendor: Oracle Corporation
System.out.printf("JVM version: %s\n", JAVA_VM_VERSION); // JVM version: 11.0.12+8-LTS-237

System.out.printf("Username: %s\n", getUserName()); // Username: johndoe
System.out.printf("Hostname: %s\n", getHostName()); // Hostname: garage-pc

var processor = getProcessor();
System.out.printf("CPU arch: %s\n", processor.getArch())  // CPU arch: BIT_64
System.out.printf("CPU type: %s\n", processor.getType()); // CPU type: X86

其他回答

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

不是你想要的,但是我建议你从common -lang3中查看ArchUtils和SystemUtils。它们还包含一些相关的辅助工具,例如:

import static org.apache.commons.lang3.ArchUtils.*;
import static org.apache.commons.lang3.SystemUtils.*;

System.out.printf("OS architecture: %s\n", OS_ARCH); // OS architecture: amd64
System.out.printf("OS name: %s\n", OS_NAME);         // OS name: Linux
System.out.printf("OS version: %s\n", OS_VERSION);   // OS version: 5.18.16-200.fc36.x86_64

System.out.printf("Is Linux? - %b\n", IS_OS_LINUX);     // Is Linux? - true
System.out.printf("Is Mac? - %b\n", IS_OS_MAC);         // Is Mac? - false
System.out.printf("Is Windows? - %b\n", IS_OS_WINDOWS); // Is Windows? - false

System.out.printf("JVM name: %s\n", JAVA_VM_NAME);       // JVM name: Java HotSpot(TM) 64-Bit Server VM
System.out.printf("JVM vendor: %s\n", JAVA_VM_VENDOR);   // JVM vendor: Oracle Corporation
System.out.printf("JVM version: %s\n", JAVA_VM_VERSION); // JVM version: 11.0.12+8-LTS-237

System.out.printf("Username: %s\n", getUserName()); // Username: johndoe
System.out.printf("Hostname: %s\n", getHostName()); // Hostname: garage-pc

var processor = getProcessor();
System.out.printf("CPU arch: %s\n", processor.getArch())  // CPU arch: BIT_64
System.out.printf("CPU type: %s\n", processor.getType()); // CPU type: X86

一个简单的方法可以用来获得操作系统级别的信息,我在我的Mac上测试,效果很好:

 OperatingSystemMXBean osBean =
        (OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
    return osBean.getProcessCpuLoad();

您可以在这里找到操作系统的许多相关指标

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

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();
        }
    }
}