CPU load from Java

2020-02-10 02:30发布

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

6条回答
够拽才男人
2楼-- · 2020-02-10 03:08

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.

查看更多
看我几分像从前
3楼-- · 2020-02-10 03:08

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.

查看更多
We Are One
4楼-- · 2020-02-10 03:11
\"骚年 ilove
5楼-- · 2020-02-10 03:14

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.

查看更多
Luminary・发光体
6楼-- · 2020-02-10 03:31

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;
            }
        }
    }
    
查看更多
Emotional °昔
7楼-- · 2020-02-10 03:34

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();
}
查看更多
登录 后发表回答