获取操作系统级别的系统信息
我目前正在构build一个Java应用程序,最终可能会在许多不同的平台上运行,但主要是Solaris,Linux和Windows的变体。
有没有人能够成功地提取信息,如当前使用的磁盘空间,CPU利用率和底层操作系统中使用的内存? 那么Java应用程序本身在消费什么呢?
最好我不想使用JNI来获取这些信息。
您可以从运行时类获取一些有限的内存信息。 这实际上不是你正在寻找的东西,但我想我会提供它的完整性。 这是一个小例子。 编辑:您也可以从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包提供了比Runtime更多的信息 – 例如,它将为您提供堆内存( ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()
)与非堆内存( ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()
)。
你也可以获得进程CPU的使用(不用编写你自己的JNI代码),但是你需要把java.lang.management.OperatingSystemMXBean
转换为com.sun.management.OperatingSystemMXBean
。 这适用于Windows和Linux,我没有在其他地方testing过。
例如…更频繁地调用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 。 它适用于大多数主要操作系统(几乎任何现代化的东西),并且非常容易操作。 开发者在他们的论坛和邮件列表上响应很快。 我也喜欢它是Apache许可的 GPL2 。 他们也提供了很多Java的例子!
SIGAR ==系统信息,收集和报告工具。
有一个Java项目使用JNA(所以没有本地库安装),并在积极的发展。 它目前支持Linux,OSX,Windows,Solaris和FreeBSD,并提供RAM,CPU,电池和文件系统信息。
您可以使用System.getenv()
获取一些系统级信息,并将相关的环境variables名称作为parameter passing。 例如,在Windows上:
System.getenv("PROCESSOR_IDENTIFIER") System.getenv("PROCESSOR_ARCHITECTURE") System.getenv("PROCESSOR_ARCHITEW6432") System.getenv("NUMBER_OF_PROCESSORS")
对于其他操作系统,相关环境variables的存在/不存在和名称将有所不同。
对于窗户,我走了这条路。
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();
这里是详细的链接 。
看看java.lang.management包中可用的API。 例如:
-
OperatingSystemMXBean.getSystemLoadAverage()
-
ThreadMXBean.getCurrentThreadCpuTime()
-
ThreadMXBean.getCurrentThreadUserTime()
那里还有很多其他有用的东西。
通常,要获得低级别的操作系统信息,您可以调用特定于操作系统的命令,这些命令使用Runtime.exec()提供所需的信息,或者在Linux中读取/ proc / *等文件。
CPU使用率并不简单 – 通过com.sun.management.OperatingSystemMXBean.getProcessCpuTime的java.lang.management接近(请参阅上面的Patrick的优秀代码片段),但请注意,它只允许访问CPU花费在您的进程中的时间。 它不会告诉您在其他进程中花费的CPU时间,甚至不会花费CPU时间来处理与您的进程相关的系统活动。
例如我有一个networking密集型的java进程 – 这是运行的唯一的东西,CPU是99%,但只有55%被报告为“处理器CPU”。
甚至没有让我开始“平均负载”,因为它接近无用,尽pipe是MX bean上唯一与cpu相关的项目。 如果只是在他们偶尔的智慧暴露像“getTotalCpuTime”的东西… … –
对于严肃的CPU监控,Matt提到的SIGAR似乎是最好的select。
它仍在开发中,但你已经可以使用jHardware了
这是一个简单的库,使用Java碎片系统数据。 它适用于Linux和Windows。
ProcessorInfo info = HardwareInfo.getProcessorInfo(); //Get named info System.out.println("Cache size: " + info.getCacheSize()); System.out.println("Family: " + info.getFamily()); System.out.println("Speed (Mhz): " + info.getMhz()); //[...]
如果您使用的是Jrockit虚拟机,那么这是获取虚拟机CPU使用率的另一种方法。 运行时bean也可以给你每个处理器的CPU负载。 我只在Red Hat Linux上用这个来观察Tomcat的性能。 您必须启用catalina.sh中的JMX远程工作。
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://my.tomcat.host:8080/jmxrmi"); JMXConnector jmxc = JMXConnectorFactory.connect(url, null); MBeanServerConnection conn = jmxc.getMBeanServerConnection(); ObjectName name = new ObjectName("oracle.jrockit.management:type=Runtime"); Double jvmCpuLoad =(Double)conn.getAttribute(name, "VMGeneratedCPULoad");
通过maven添加OSHI依赖关系:
<dependency> <groupId>com.github.dblock</groupId> <artifactId>oshi-core</artifactId> <version>2.2</version> </dependency>
以百分比获得电池容量:
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)); }
嘿,你可以做到这一点与Java / COM集成。 通过访问WMIfunction,您可以获取所有信息。
在Windows
,您可以运行systeminfo
命令并检索其输出,例如使用以下代码:
private static class WindowsSystemInformation { static String get() throws IOException { Runtime runtime = Runtime.getRuntime(); Process process = runtime.exec("systeminfo"); BufferedReader systemInformationReader = new BufferedReader(new InputStreamReader(process.getInputStream())); StringBuilder stringBuilder = new StringBuilder(); String line; while ((line = systemInformationReader.readLine()) != null) { stringBuilder.append(line); stringBuilder.append(System.lineSeparator()); } return stringBuilder.toString().trim(); } }
- PHP 5.3.3中的ini_set(“memory_limit”)根本不起作用
- stringstream,string和char *转换混淆
- 我应该如何以高效的内存方式将string键映射到Java中的值?
- Python结构的内存大小
- Python subprocess.Popen“OSError:无法分配内存”
- 什么是glibc免费/ malloc / realloc无效的下一个大小/无效指针错误,以及如何解决它?
- Java安全性:如何清除/清零与对象关联的内存? (和/或确保这是唯一的实例/特定variables的副本)
- java.lang.OutOfMemoryError:位图大小超过VM预算 – Android
- 声明大型数组时发生堆栈溢出exception