Java 获取操作系统级别的系统信息
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25552/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Get OS-level system information
提问by Steve M
I'm currently building a Java app that could end up being run on many different platforms, but primarily variants of Solaris, Linux and Windows.
我目前正在构建一个 Java 应用程序,该应用程序最终可以在许多不同的平台上运行,但主要是 Solaris、Linux 和 Windows 的变体。
Has anyone been able to successfully extract information such as the current disk space used, CPU utilisation and memory used in the underlying OS? What about just what the Java app itself is consuming?
有没有人能够成功提取信息,例如当前使用的磁盘空间、CPU 利用率和底层操作系统中使用的内存?Java 应用程序本身正在消耗什么?
Preferrably I'd like to get this information without using JNI.
最好我想在不使用 JNI 的情况下获取这些信息。
采纳答案by William Brendel
You can get some limited memory information from the Runtime class. It really isn't exactly what you are looking for, but I thought I would provide it for the sake of completeness. Here is a small example. Edit: You can also get disk usage information from the java.io.File class. The disk space usage stuff requires Java 1.6 or higher.
您可以从 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());
}
}
}
回答by Matt Cummings
I think the best method out there is to implement the SIGAR API by Hyperic. It works for most of the major operating systems ( darn near anything modern ) and is very easy to work with. The developer(s) are very responsive on their forum and mailing lists. I also like that it is GPL2Apache licensed. They provide a ton of examples in Java too!
我认为最好的方法是通过 Hyperic实现SIGAR API。它适用于大多数主要操作系统(几乎接近任何现代操作系统)并且非常易于使用。开发人员对他们的论坛和邮件列表非常敏感。我也喜欢它是GPL2 Apache 许可的。他们也提供了大量 Java 示例!
回答by staffan
Have a look at the APIs available in the java.lang.managementpackage. For example:
查看java.lang.management包中可用的 API 。例如:
OperatingSystemMXBean.getSystemLoadAverage()
ThreadMXBean.getCurrentThreadCpuTime()
ThreadMXBean.getCurrentThreadUserTime()
OperatingSystemMXBean.getSystemLoadAverage()
ThreadMXBean.getCurrentThreadCpuTime()
ThreadMXBean.getCurrentThreadUserTime()
There are loads of other useful things in there as well.
还有很多其他有用的东西。
回答by Patrick Wilkes
The java.lang.managementpackage does give you a whole lot more info than Runtime - for example it will give you heap memory (ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()
) separate from non-heap memory (ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()
).
该java.lang.management包确实给你比运行了一大堆更多信息-例如,它会给你堆内存(ManagementFactory.getMemoryMXBean().getHeapMemoryUsage()
)从非堆内存分开(ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage()
)。
You can also get process CPU usage (without writing your own JNI code), but you need to cast the java.lang.management.OperatingSystemMXBean
to a com.sun.management.OperatingSystemMXBean
. This works on Windows and Linux, I haven't tested it elsewhere.
您还可以得到处理的CPU使用率(无需编写自己的JNI代码),但你需要转换java.lang.management.OperatingSystemMXBean
到com.sun.management.OperatingSystemMXBean
。这适用于 Windows 和 Linux,我没有在其他地方测试过。
For example ... call the get getCpuUsage() method more frequently to get more accurate readings.
例如...更频繁地调用 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();
}
}
}
回答by Patrick Wilkes
Hey you can do this with java/com integration. By accessing WMI features you can get all the information.
嘿,您可以通过 java/com 集成来做到这一点。通过访问 WMI 功能,您可以获得所有信息。
回答by Peter Lawrey
Usually, to get low level OS information you can call OS specific commands which give you the information you want with Runtime.exec() or read files such as /proc/* in Linux.
通常,要获取低级操作系统信息,您可以调用操作系统特定命令,这些命令为您提供所需的信息 Runtime.exec() 或读取文件,例如 Linux 中的 /proc/*。
回答by Partly Cloudy
CPU usage isn't straightforward -- java.lang.management via com.sun.management.OperatingSystemMXBean.getProcessCpuTime comes close (see Patrick's excellent code snippet above) but note that it only gives access to time the CPU spent in your process. it won't tell you about CPU time spent in other processes, or even CPU time spent doing system activities related to your process.
CPU 使用率并不简单——通过 com.sun.management.OperatingSystemMXBean.getProcessCpuTime 的 java.lang.management 很接近(请参阅上面帕特里克的优秀代码片段),但请注意,它只允许访问 CPU 在您的进程中花费的时间。它不会告诉您在其他进程中花费的 CPU 时间,甚至不会告诉您执行与您的进程相关的系统活动所花费的 CPU 时间。
for instance i have a network-intensive java process -- it's the only thing running and the CPU is at 99% but only 55% of that is reported as "processor CPU".
例如,我有一个网络密集型 java 进程——它是唯一运行的东西,CPU 为 99%,但只有 55% 被报告为“处理器 CPU”。
don't even get me started on "load average" as it's next to useless, despite being the only cpu-related item on the MX bean. if only sun in their occasional wisdom exposed something like "getTotalCpuTime"...
甚至不要让我开始使用“平均负载”,因为它几乎没用,尽管它是 MX bean 上唯一与 CPU 相关的项目。如果只有阳光在他们偶尔的智慧中暴露了诸如“getTotalCpuTime”之类的东西......
for serious CPU monitoring SIGAR mentioned by Matt seems the best bet.
对于认真的 CPU 监控,Matt 提到的 SIGAR 似乎是最好的选择。
回答by dB.
There's a Java project that uses JNA (so no native libraries to install) and is in active development. It currently supports Linux, OSX, Windows, Solaris and FreeBSD and provides RAM, CPU, Battery and file system information.
有一个使用 JNA 的 Java 项目(因此无需安装本机库)并且正在积极开发中。它目前支持 Linux、OSX、Windows、Solaris 和 FreeBSD,并提供 RAM、CPU、电池和文件系统信息。
回答by petro
If you are using Jrockit VM then here is an other way of getting VM CPU usage. Runtime bean can also give you CPU load per processor. I have used this only on Red Hat Linux to observer Tomcat performance. You have to enable JMX remote in catalina.sh for this to work.
如果您使用的是 Jrockit VM,那么这里是获取 VM 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");
回答by Alexandr
You can get some system-level information by using System.getenv()
, passing the relevant environment variable name as a parameter. For example, on Windows:
您可以通过使用System.getenv()
,将相关环境变量名称作为参数传递来获取一些系统级信息。例如,在 Windows 上:
System.getenv("PROCESSOR_IDENTIFIER")
System.getenv("PROCESSOR_ARCHITECTURE")
System.getenv("PROCESSOR_ARCHITEW6432")
System.getenv("NUMBER_OF_PROCESSORS")
For other operating systems the presence/absence and names of the relevant environment variables will differ.
对于其他操作系统,相关环境变量的存在/不存在和名称会有所不同。