获取操作系统级别的系统信息
我目前正在构建一个Java应用程序,该应用程序最终可能会在许多不同的平台上运行,但主要是Solaris,Linux和Windows的变体。
是否有人能够成功提取信息,例如当前使用的磁盘空间,CPU利用率和底层操作系统中使用的内存? Java应用程序本身正在消耗什么呢?
最好是我不使用JNI来获取此信息。
解决方案
回答
我认为最好的方法是通过Hyperic实现SIGAR API。它适用于大多数主要操作系统(几乎是任何现代操作系统),并且非常易于使用。开发人员对他们的论坛和邮件列表的响应非常迅速。我也喜欢它是GPL2 Apache许可的。他们也提供了很多Java示例!
SIGAR ==系统信息,收集和报告工具。
回答
我们可以从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包中可用的API。例如:
OperatingSystemMXBean.getSystemLoadAverage()
ThreadMXBean.getCurrentThreadCpuTime()
ThreadMXBean.getCurrentThreadUserTime()
那里还有许多其他有用的东西。
回答
与运行时相比,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(); } } }
回答
嘿,我们可以通过java / com集成来做到这一点。通过访问WMI功能,我们可以获得所有信息。
回答
通常,要获取底层OS信息,我们可以调用特定于OS的命令,这些命令通过Runtime.exec()为我们提供所需的信息,或者在Linux中读取文件/ proc / *。
回答
CPU的使用不是很简单-通过com.sun.management.OperatingSystemMXBean.getProcessCpuTime的java.lang.management接近(请参见上面的Patrick出色的代码片段),但请注意,它仅提供访问CPU在进程中花费的时间的权限。它不会告诉我们其他进程所花费的CPU时间,甚至不会告诉我们执行与进程相关的系统活动所花费的CPU时间。
例如,我有一个网络密集型的Java进程-它是唯一运行的进程,CPU处于99%的状态,但是只有55%的报告为"处理器CPU"。
尽管它是MX bean上唯一与CPU相关的项目,但它甚至让我从"平均负载"开始,因为它几乎没有用。如果只有太阳在他们偶尔的智慧中暴露出诸如" getTotalCpuTime"之类的东西...
Matt提到对SIGAR进行认真的CPU监视似乎是最好的选择。
回答
有一个Java项目使用JNA(因此无需安装本机库)并且正在积极开发中。它目前支持Linux,OSX,Windows,Solaris和FreeBSD,并提供RAM,CPU,电池和文件系统信息。
- https://github.com/oshi/oshi