代码之家  ›  专栏  ›  技术社区  ›  paweloque

来自Java的CPU负载

  •  17
  • paweloque  · 技术社区  · 15 年前

    有没有一种方法可以在不使用JNI的情况下获得Java下的当前cpu负载?

    6 回复  |  直到 15 年前
        1
  •  26
  •   Bob Cross n8wrl    15 年前
        2
  •  6
  •   Kaido Kalda    12 年前

    getSystemLoadAverage()

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

    • getTotalUsage()
    • Getavaraguesageperpu()
    • getUsageByThread(线程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<Long, ThreadTime> threadTimeMap = new HashMap<Long, ThreadTime>();
          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<Long> mappedIds;
                  synchronized (threadTimeMap) {
                      mappedIds = new HashSet<Long>(threadTimeMap.keySet());
                  }
      
                  long[] allThreadIds = threadBean.getAllThreadIds();
      
                  removeDeadThreads(mappedIds, allThreadIds);
      
                  mapNewThreads(allThreadIds);
      
                  Collection<ThreadTime> values;
                  synchronized (threadTimeMap) {
                      values = new HashSet<ThreadTime>(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<Long> 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<ThreadTime> values;
              synchronized (threadTimeMap) {
                  values = new HashSet<ThreadTime>(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;
              }
          }
      }
      
        3
  •  5
  •   Alex Miller    15 年前

    这确实涉及JNI,但Hyperic有一个名为 Sigar

        4
  •  4
  •   welterde    15 年前

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

        5
  •  1
  •   Bombe    15 年前

    在Linux下,您可以使用 Runtime . exec() 执行正常运行时间并评估输出。我认为在Linux下没有更好的方法,在Windows下也没有同样方便的方法。

        6
  •  0
  •   Kire Haglin    15 年前

    如果你正在使用 JRockit JVM JMAPI . 它适用于JDK1.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();
    }