来自Java的CPU负载

有没有办法在不使用JNI的情况下获取Java下的当前cpu负载?

使用ManagementFactory获取OperatingSystemMXBean并在其上调用getSystemLoadAverage()

这确实涉及JNI,但Hyperic中有一个名为Sigar的GPL库,它为所有主要平台提供此信息,以及一些其他依赖于操作系统的统计信息,如磁盘使用情况。 它对我们很有用。

getSystemLoadAverage()为您提供超过1分钟的值(每秒刷新一次),并为整个操作系统提供此值。 应通过分别监视每个线程来完成更多实时概述。 重要的是还要注意监视刷新间隔 – 更常见的是检查值,在给定时刻更准确,如果每隔毫秒执行一次,则通常为0或100(或者更多,具体取决于CPU的数量)。 但是如果我们允许时间范围(例如1秒),我们会在这段时间内得到平均值,并获得更多信息。 此外,重要的是要注意,只有一个线程占用多个CPU(核心)的可能性极小。

以下实现允许使用3种方法:

  • getTotalUsage() – JVM中所有线程的总负载
  • getAvarageUsagePerCPU() – 每CPU的容量负载(核心)
  • getUsageByThread(Thread t) – 指定线程的总加载量

     import java.lang.management.ManagementFactory; import java.lang.management.OperatingSystemMXBean; import java.lang.management.ThreadMXBean; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; public class MonitoringThread extends Thread { private long refreshInterval; private boolean stopped; private Map threadTimeMap = new HashMap(); private ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); private OperatingSystemMXBean opBean = ManagementFactory.getOperatingSystemMXBean(); public MonitoringThread(long refreshInterval) { this.refreshInterval = refreshInterval; setName("MonitoringThread"); start(); } @Override public void run() { while(!stopped) { Set mappedIds; synchronized (threadTimeMap) { mappedIds = new HashSet(threadTimeMap.keySet()); } long[] allThreadIds = threadBean.getAllThreadIds(); removeDeadThreads(mappedIds, allThreadIds); mapNewThreads(allThreadIds); Collection values; synchronized (threadTimeMap) { values = new HashSet(threadTimeMap.values()); } for (ThreadTime threadTime : values) { synchronized (threadTime) { threadTime.setCurrent(threadBean.getThreadCpuTime(threadTime.getId())); } } try { Thread.sleep(refreshInterval); } catch (InterruptedException e) { throw new RuntimeException(e); } for (ThreadTime threadTime : values) { synchronized (threadTime) { threadTime.setLast(threadTime.getCurrent()); } } } } private void mapNewThreads(long[] allThreadIds) { for (long id : allThreadIds) { synchronized (threadTimeMap) { if(!threadTimeMap.containsKey(id)) threadTimeMap.put(id, new ThreadTime(id)); } } } private void removeDeadThreads(Set mappedIds, long[] allThreadIds) { outer: for (long id1 : mappedIds) { for (long id2 : allThreadIds) { if(id1 == id2) continue outer; } synchronized (threadTimeMap) { threadTimeMap.remove(id1); } } } public void stopMonitor() { this.stopped = true; } public double getTotalUsage() { Collection values; synchronized (threadTimeMap) { values = new HashSet(threadTimeMap.values()); } double usage = 0D; for (ThreadTime threadTime : values) { synchronized (threadTime) { usage += (threadTime.getCurrent() - threadTime.getLast()) / (refreshInterval * 10000); } } return usage; } public double getAvarageUsagePerCPU() { return getTotalUsage() / opBean.getAvailableProcessors(); } public double getUsageByThread(Thread t) { ThreadTime info; synchronized (threadTimeMap) { info = threadTimeMap.get(t.getId()); } double usage = 0D; if(info != null) { synchronized (info) { usage = (info.getCurrent() - info.getLast()) / (refreshInterval * 10000); } } return usage; } static class ThreadTime { private long id; private long last; private long current; public ThreadTime(long id) { this.id = id; } public long getId() { return id; } public long getLast() { return last; } public void setLast(long last) { this.last = last; } public long getCurrent() { return current; } public void setCurrent(long current) { this.current = current; } } } 

在linux上你可以只读取文件/ proc / loadavg,其中前三个值代表负载平均值。 对于Windows,您可能必须坚持使用JNI。

在Linux下你可以使用Runtime 。 exec()执行“uptime”并评估输出。 我不认为在Linux下有更好的方法,我认为Windows下没有同样“方便”的方式。

如果您使用的是JRockit JVM ,则可以使用JMAPI 。 它适用于JDK 1.4,1.5和1.6。

 System.out.println("Total CPU-usage:" + JVMFactory.getJVM().getMachine().getCPULoad()); System.out.println("Total JVM-load :" + JVMFactory.getJVM().getJVMLoad()); for(Iterator it = JVMFactory.getJVM().getMachine().getCPUs().iterator(); it.hasNext();) { CPU cpu = (CPU)it.next(); System.out.println("CPU Description: " + cpu.getDescription()); System.out.println("CPU Clock Frequency: " + cpu.getClockFrequency()); System.out.println("CPU Load: " + cpu.getLoad()); System.out.println(); }