Подтвердить что ты не робот

Загрузка процессора с Java

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

4b9b3361

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

Если вы используете 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();
}