Загрузка процессора с Java - PullRequest
17 голосов
/ 11 марта 2009

Есть ли способ получить текущую загрузку процессора под Java без использования JNI?

Ответы [ 6 ]

25 голосов
/ 11 марта 2009

Используйте ManagementFactory, чтобы получить OperatingSystemMXBean и позвоните getSystemLoadAverage().

5 голосов
/ 05 августа 2012

getSystemLoadAverage () дает вам значение за 1 минуту времени (обновляется каждую секунду) и дает это значение для всей операционной системы. Более подробный обзор в реальном времени должен быть сделан путем мониторинга каждого потока в отдельности. Важно также обратить внимание на интервал обновления мониторинга - чаще вы проверяете значение, тем точнее оно находится в данный момент, и если вы делаете это каждую миллисекунду, оно обычно равно 0 или 100 (или больше, в зависимости от количества процессоров). Но если мы допустим таймфрейм (например, 1 секунду), мы получаем среднее значение за этот период времени и получаем более информативный результат. Также важно отметить, что маловероятно, что только один поток занимает более одного ЦП (ядра).

Следующая реализация позволяет использовать 3 метода:

  • getTotalUsage () - Общая загрузка всех потоков в JVM
  • getAvarageUsagePerCPU () - средняя нагрузка на процессор (ядро)
  • 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<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;
            }
        }
    }
    
5 голосов
/ 11 марта 2009

Это касается JNI, но есть библиотека GPL от Hyperic под названием Sigar , которая предоставляет эту информацию для всех основных платформ, а также множество других зависящих от ОС статистических данных, таких как использование диска. Это отлично сработало для нас.

2 голосов
/ 11 марта 2009

В Linux вы можете просто прочитать файл / proc / loadavg, где первые три значения представляют средние значения загрузки. Для Windows вы, вероятно, должны придерживаться JNI.

1 голос
/ 11 марта 2009

В Linux вы можете использовать Runtime . exec () , чтобы выполнить «uptime» и оценить вывод. Я не считаю, что под Linux есть лучший способ, и я не думаю, что под Windows есть такой же «удобный» способ.

0 голосов
/ 16 марта 2009

Если вы используете 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...