我目前正在构建一个Java应用程序,它最终可以在许多不同的平台上运行,但主要是Solaris、Linux和Windows的变体。
是否有人能够成功地提取诸如当前使用的磁盘空间、CPU利用率和底层操作系统中使用的内存等信息?Java应用程序本身正在消耗什么呢?
我希望在不使用JNI的情况下获得这些信息。
我目前正在构建一个Java应用程序,它最终可以在许多不同的平台上运行,但主要是Solaris、Linux和Windows的变体。
是否有人能够成功地提取诸如当前使用的磁盘空间、CPU利用率和底层操作系统中使用的内存等信息?Java应用程序本身正在消耗什么呢?
我希望在不使用JNI的情况下获得这些信息。
当前回答
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();
}
}
}
其他回答
您可以使用System.getenv()获取一些系统级信息,并将相关的环境变量名作为参数传递。例如,在Windows上:
System.getenv("PROCESSOR_IDENTIFIER")
System.getenv("PROCESSOR_ARCHITECTURE")
System.getenv("PROCESSOR_ARCHITEW6432")
System.getenv("NUMBER_OF_PROCESSORS")
对于其他操作系统,相关环境变量的存在/不存在和名称将有所不同。
通常,为了获得较低级别的操作系统信息,您可以通过Runtime.exec()调用特定于操作系统的命令,这些命令会提供您想要的信息,或者读取Linux中的/proc/*等文件。
一个简单的方法可以用来获得操作系统级别的信息,我在我的Mac上测试,效果很好:
OperatingSystemMXBean osBean =
(OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
return osBean.getProcessCpuLoad();
您可以在这里找到操作系统的许多相关指标
如果您正在使用Jrockit虚拟机,那么这里有另一种获取虚拟机CPU使用情况的方法。运行时bean还可以提供每个处理器的CPU负载。我只在Red Hat Linux上使用它来观察Tomcat性能。您必须在catalina.sh中启用JMX remote才能使其工作。
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");
看一下java.lang.management包中可用的api。例如:
OperatingSystemMXBean.getSystemLoadAverage () ThreadMXBean.getCurrentThreadCpuTime () ThreadMXBean.getCurrentThreadUserTime ()
还有很多其他有用的东西。