来自 Java 的 CPU 负载

发布于 2024-07-15 01:49:51 字数 34 浏览 5 评论 0原文

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

Is there a way to get the current cpu load under Java without using the JNI?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

趁年轻赶紧闹 2024-07-22 01:49:51

getSystemLoadAverage() 为您提供 1 分钟内的值(每秒刷新一次),并给出整个操作系统的该值。 应通过单独监视每个线程来完成更多实时概述。 还需要注意的是监视刷新间隔 - 您检查该值的频率越高,在给定时刻的值就越精确,如果您每毫秒执行一次,则它通常为 0 或 100(或更多,具体取决于有多少个 CPU)。 但是,如果我们允许时间范围(例如 1 秒),我们就会得到这段时间的平均值,并且得到信息更丰富的结果。 另外,值得注意的是,只有一个线程占用多个 CPU(核心)的可能性极小。

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

  • getTotalUsage() - JVM 中所有线程的总负载
  • getAvarageUsagePerCPU() - 每个 CPU(核心)的平均负载
  • getUsageByThread(Thread t) - 指定线程的总负载

    导入java.lang.management.ManagementFactory; 
      导入 java.lang.management.OperatingSystemMXBean; 
      导入 java.lang.management.ThreadMXBean; 
      导入java.util.Collection; 
      导入java.util.HashMap; 
      导入java.util.HashSet; 
      导入java.util.Map; 
      导入java.util.Set; 
    
      公共类MonitoringThread扩展Thread { 
    
          私有长刷新间隔; 
          私人布尔值停止; 
    
          private Map   threadTimeMap = new HashMap(); 
          私有 ThreadMXBean threadBean = ManagementFactory.getThreadMXBean(); 
          私有 OperatingSystemMXBean opBean = ManagementFactory.getOperatingSystemMXBean(); 
    
          公共监控线程(长刷新间隔){ 
              this.refreshInterval = 刷新间隔; 
    
              setName("监控线程"); 
    
              开始(); 
          } 
    
          @覆盖 
          公共无效运行(){ 
              while(!stopped) { 
                  设置<长>   映射的 ID; 
                  同步(线程时间映射){ 
                      mappedIds = new HashSet(threadTimeMap.keySet()); 
                  } 
    
                  long[] allThreadIds = threadBean.getAllThreadIds(); 
    
                  删除DeadThreads(mappedIds,allThreadIds); 
    
                  mapNewThreads(allThreadIds); 
    
                  集合   价值观; 
                  同步(线程时间映射){ 
                      value = new HashSet(threadTimeMap.values());     
                  } 
    
                  for (ThreadTime 线程时间:值) { 
                      同步(线程时间){ 
                          threadTime.setCurrent(threadBean.getThreadCpuTime(threadTime.getId()));  
                      } 
                  } 
    
                  尝试 { 
                      Thread.sleep(刷新间隔); 
                  } catch (InterruptedException e) { 
                      抛出新的运行时异常(e); 
                  } 
    
                  for (ThreadTime 线程时间:值) { 
                      同步(线程时间){ 
                          threadTime.setLast(threadTime.getCurrent());     
                      } 
                  } 
              } 
          } 
    
          私有无效mapNewThreads(长[] allThreadIds){ 
              for (长 id : allThreadIds) { 
                  同步(线程时间映射){ 
                      if(!threadTimeMap.containsKey(id)) 
                          threadTimeMap.put(id, new ThreadTime(id)); 
                  } 
              } 
          } 
    
          private void removeDeadThreads(Setma​​ppedIds, long[] allThreadIds) { 
              外部:for(长id1:mappedIds){ 
                  for (long id2 : allThreadIds) { 
                      如果(id1==id2) 
                          继续外; 
                  } 
                  同步(线程时间映射){ 
                      threadTimeMap.remove(id1); 
                  } 
              } 
          } 
    
          公共无效停止监视器(){ 
              this.stopped = true; 
          } 
    
          公共双 getTotalUsage() { 
              集合   价值观; 
              同步(线程时间映射){ 
                  value = new HashSet(threadTimeMap.values());     
              } 
    
              双重使用 = 0D; 
              for (ThreadTime 线程时间:值) { 
                  同步(线程时间){ 
                      用法 += (threadTime.getCurrent() - threadTime.getLast()) / (refreshInterval * 10000); 
                  } 
              } 
              返回使用情况; 
          } 
    
          公共双 getAvarageUsagePerCPU() { 
              返回 getTotalUsage() / opBean.getAvailableProcessors();  
          } 
    
          公共双 getUsageByThread(线程 t) { 
              线程时间信息; 
              同步(线程时间映射){ 
                  信息 = threadTimeMap.get(t.getId()); 
              } 
    
              双重使用 = 0D; 
              如果(信息!=空){ 
                  同步(信息){ 
                      用法 = (info.getCurrent() - info.getLast()) / (refreshInterval * 10000); 
                  } 
              } 
              返回使用情况; 
          } 
    
          静态类 ThreadTime { 
    
              私人长ID; 
              私人长久以来; 
              私人长电; 
    
              公共线程时间(长ID){ 
                  这个.id = id; 
              } 
    
              公共长 getId() { 
                  返回ID; 
              } 
    
              公共长 getLast() { 
                  最后返回; 
              } 
    
              公共无效setLast(最后){ 
                  这.最后=最后; 
              } 
    
              公共长 getCurrent() { 
                  返回电流; 
              } 
    
              公共无效setCurrent(长电流){ 
                  this.current = 当前; 
              } 
          } 
      } 
      

getSystemLoadAverage() gives you value over 1 minute of time (refreshes every second) and gives this value for overall operating system. More realtime overview should be done by monitoring each thread separately. Important is also notice the monitoring refresh interval - more often you check the value, more precice it is in given moment and if you do it every millisecond, it is typically 0 or 100 (or more depending how many CPU's is there). But if we allow timeframe (for example 1 second), we get avarage over this period of time and we get more informative result. Also, it is important to notice, that it is highly unlikely, that only one thread occupies more than one CPU (core).

Following implementation allows to use 3 methods:

  • getTotalUsage() - Total load by all the threads in JVM
  • getAvarageUsagePerCPU() - Avarage load per CPU (core)
  • getUsageByThread(Thread t) - Total load by specified thread

    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;
            }
        }
    }
    
烂柯人 2024-07-22 01:49:51

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

This does involve JNI but there is a GPL library from Hyperic called Sigar that provides this information for all the major platforms, as well as a bunch of other OS-dependent stats like disk usage. It's worked great for us.

月下伊人醉 2024-07-22 01:49:51

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

On linux you could just read the file /proc/loadavg, where the first three values represent the load averages. For Windows you probably have to stick to JNI.

青瓷清茶倾城歌 2024-07-22 01:49:51

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

Under Linux you could use Runtime.exec() to execute “uptime” and evaluate the output. I don’t there’s a better way under Linux, and I don’t think there’s an equally “convenient” way under Windows.

蛮可爱 2024-07-22 01:49:51

如果您使用 JRockit JVM 您可以使用 < a href="http://download.oracle.com/docs/cd/E13150_01/jrockit_jvm/jrockit/releases/R27/javadoc/manapi27.2/docs/index.html" rel="nofollow noreferrer">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();
}

If you're using the JRockit JVM you could use JMAPI. It works for JDK 1.4, 1.5 and 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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文