Как отслеживать использование процессора, памяти и диска компьютера в Java?

StackOverflow https://stackoverflow.com/questions/47177

Вопрос

Я хотел бы отслеживать следующую системную информацию в Java:

  • Текущая загрузка ЦП** (в процентах)
  • Доступная память* (свободная/общая)
  • Доступное дисковое пространство (свободное/общее)

    *Обратите внимание, что я имею в виду общую память, доступную всей системе, а не только JVM.

Я ищу кроссплатформенное решение (Linux, Mac и Windows), которое не полагается на мой собственный код, вызывающий внешние программы или использующий JNI.Хотя это жизнеспособные варианты, я бы предпочел не поддерживать код, специфичный для ОС, если у кого-то уже есть лучшее решение.

Если есть бесплатная библиотека, которая делает это надежным и кроссплатформенным способом, это было бы здорово (даже если она выполняет внешние вызовы или сама использует собственный код).

Любые предложения очень ценятся.

Чтобы уточнить, я хотел бы получить текущую загрузку ЦП для всей системы, а не только для процессов Java.

SIGAR API предоставляет все функции, которые мне нужны, в одном пакете, поэтому на данный момент это лучший ответ на мой вопрос.Однако, поскольку он распространяется под лицензией GPL, я не могу использовать его по своему первоначальному назначению (коммерческий продукт с закрытым исходным кодом).Вполне возможно, что Hyperic лицензирует SIGAR для коммерческого использования, но я не рассматривал этот вопрос.Для своих проектов под лицензией GPL я обязательно рассмотрю SIGAR в будущем.

Для моих текущих потребностей я склоняюсь к следующему:

  • Для использования процессора OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors() (средняя нагрузка на процессор)
  • На память, OperatingSystemMXBean.getTotalPhysicalMemorySize() и OperatingSystemMXBean.getFreePhysicalMemorySize()
  • Что касается дискового пространства, File.getTotalSpace() и File.getUsableSpace()

Ограничения:

А getSystemLoadAverage() и методы запроса дискового пространства доступны только в Java 6.Кроме того, некоторые функции JMX могут быть доступны не для всех платформ (т. е.сообщалось, что getSystemLoadAverage() возвращает -1 в Windows).

Хотя изначально лицензия распространялась по лицензии GPL, она был изменен к Апач 2.0, который обычно можно использовать для коммерческих продуктов с закрытым исходным кодом.

Это было полезно?

Решение

В духе того, что я упомянул в этом посте.Я рекомендую вам использовать СИГАР API.Я использую SIGAR API в одном из своих приложений, и это здорово.Вы обнаружите, что он стабилен, хорошо поддерживается и полон полезных примеров.Это открытый исходный код с Лицензия GPL 2 Лицензия Апач 2.0.Проверьте это.Я чувствую, что это удовлетворит ваши потребности.

Используя Java и Sigar API, вы можете получить информацию о памяти, процессоре, диске, средней нагрузке, сетевом интерфейсе и метрики, информацию о таблице процессов, информацию о маршруте и т. д.

Другие советы

Следующее предположительно дает вам процессор и оперативную память.Видеть УправлениеЗавод Больше подробностей.

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

private static void printUsage() {
  OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
  for (Method method : operatingSystemMXBean.getClass().getDeclaredMethods()) {
    method.setAccessible(true);
    if (method.getName().startsWith("get")
        && Modifier.isPublic(method.getModifiers())) {
            Object value;
        try {
            value = method.invoke(operatingSystemMXBean);
        } catch (Exception e) {
            value = e;
        } // try
        System.out.println(method.getName() + " = " + value);
    } // if
  } // for
}

В JDK 1.7 вы можете получить информацию об использовании системного процессора и памяти через com.sun.management.OperatingSystemMXBean.Это отличается от java.lang.management.OperatingSystemMXBean.

long    getCommittedVirtualMemorySize()
Returns the amount of virtual memory that is guaranteed to be available to the running process in bytes, or -1 if this operation is not supported.

long    getFreePhysicalMemorySize()
Returns the amount of free physical memory in bytes.

long    getFreeSwapSpaceSize()
Returns the amount of free swap space in bytes.

double  getProcessCpuLoad()
Returns the "recent cpu usage" for the Java Virtual Machine process.

long    getProcessCpuTime()
Returns the CPU time used by the process on which the Java virtual machine is running in nanoseconds.

double  getSystemCpuLoad()
Returns the "recent cpu usage" for the whole system.

long    getTotalPhysicalMemorySize()
Returns the total amount of physical memory in bytes.

long    getTotalSwapSpaceSize()
Returns the total amount of swap space in bytes.

У меня это прекрасно работает без какого-либо внешнего API, просто встроенная скрытая функция Java :)

import com.sun.management.OperatingSystemMXBean;
...
OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(
                OperatingSystemMXBean.class);
// What % CPU load this current JVM is taking, from 0.0-1.0
System.out.println(osBean.getProcessCpuLoad());

// What % load the overall system is at, from 0.0-1.0
System.out.println(osBean.getSystemCpuLoad());

Взгляните на эту очень подробную статью:http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking#UsingaSuninternalclasstogetJVMCPUtime

Чтобы получить процент использования процессора, все, что вам нужно, это простые математические вычисления:

MBeanServerConnection mbsc = ManagementFactory.getPlatformMBeanServer();

OperatingSystemMXBean osMBean = ManagementFactory.newPlatformMXBeanProxy(
mbsc, ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);

long nanoBefore = System.nanoTime();
long cpuBefore = osMBean.getProcessCpuTime();

// Call an expensive task, or sleep if you are monitoring a remote process

long cpuAfter = osMBean.getProcessCpuTime();
long nanoAfter = System.nanoTime();

long percent;
if (nanoAfter > nanoBefore)
 percent = ((cpuAfter-cpuBefore)*100L)/
   (nanoAfter-nanoBefore);
else percent = 0;

System.out.println("Cpu usage: "+percent+"%");

Примечание:Вы должны импортировать com.sun.management.OperatingSystemMXBean и не java.lang.management.OperatingSystemMXBean.

Для дискового пространства, если у вас Java 6, вы можете использовать getTotalSpace и getFreeSpace методы в файле.Если вы не используете Java 6, я думаю, вы можете использовать Apache Commons IO чтобы пройти туда немного.

Боюсь, я не знаю ни одного кроссплатформенного способа узнать загрузку процессора или память.

Многое из этого уже доступно через JMX.В Java 5 JMX встроен, и в состав JDK входит средство просмотра консоли JMX.

Вы можете использовать JMX для мониторинга вручную или вызывать команды JMX из Java, если вам нужна эта информация в вашей собственной среде выполнения.

/* YOU CAN TRY THIS TOO */

import java.io.File;
 import java.lang.management.ManagementFactory;
// import java.lang.management.OperatingSystemMXBean;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
 import java.lang.management.RuntimeMXBean;
 import java.io.*;
 import java.net.*;
 import java.util.*;
 import java.io.LineNumberReader;
 import java.lang.management.ManagementFactory;
import com.sun.management.OperatingSystemMXBean;
import java.lang.management.ManagementFactory;
import java.util.Random;



 public class Pragati
 {

     public static void printUsage(Runtime runtime)
     {
     long total, free, used;
     int mb = 1024*1024;

     total = runtime.totalMemory();
     free = runtime.freeMemory();
     used = total - free;
     System.out.println("\nTotal Memory: " + total / mb + "MB");
     System.out.println(" Memory Used: " + used / mb + "MB");
     System.out.println(" Memory Free: " + free / mb + "MB");
     System.out.println("Percent Used: " + ((double)used/(double)total)*100 + "%");
     System.out.println("Percent Free: " + ((double)free/(double)total)*100 + "%");
    }
    public static void log(Object message)
         {
            System.out.println(message);
         }

        public static int calcCPU(long cpuStartTime, long elapsedStartTime, int cpuCount)
        {
             long end = System.nanoTime();
             long totalAvailCPUTime = cpuCount * (end-elapsedStartTime);
             long totalUsedCPUTime = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime()-cpuStartTime;
             //log("Total CPU Time:" + totalUsedCPUTime + " ns.");
             //log("Total Avail CPU Time:" + totalAvailCPUTime + " ns.");
             float per = ((float)totalUsedCPUTime*100)/(float)totalAvailCPUTime;
             log( per);
             return (int)per;
        }

        static boolean isPrime(int n)
        {
     // 2 is the smallest prime
            if (n <= 2)
            {
                return n == 2;
            }
     // even numbers other than 2 are not prime
            if (n % 2 == 0)
            {
                return false;
            }
     // check odd divisors from 3
     // to the square root of n
         for (int i = 3, end = (int)Math.sqrt(n); i <= end; i += 2)
         {
            if (n % i == 0)
         {
         return false;
        }
        }
 return true;
}
    public static void main(String [] args)
    {
            int mb = 1024*1024;
            int gb = 1024*1024*1024;
             /* PHYSICAL MEMORY USAGE */
             System.out.println("\n**** Sizes in Mega Bytes ****\n");
            com.sun.management.OperatingSystemMXBean operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean)ManagementFactory.getOperatingSystemMXBean();
            //RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
            //operatingSystemMXBean = (com.sun.management.OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
            com.sun.management.OperatingSystemMXBean os = (com.sun.management.OperatingSystemMXBean)
            java.lang.management.ManagementFactory.getOperatingSystemMXBean();
            long physicalMemorySize = os.getTotalPhysicalMemorySize();
            System.out.println("PHYSICAL MEMORY DETAILS \n");
            System.out.println("total physical memory : " + physicalMemorySize / mb + "MB ");
            long physicalfreeMemorySize = os.getFreePhysicalMemorySize();
            System.out.println("total free physical memory : " + physicalfreeMemorySize / mb + "MB");
            /* DISC SPACE DETAILS */
            File diskPartition = new File("C:");
            File diskPartition1 = new File("D:");
            File diskPartition2 = new File("E:");
            long totalCapacity = diskPartition.getTotalSpace() / gb;
            long totalCapacity1 = diskPartition1.getTotalSpace() / gb;
            double freePartitionSpace = diskPartition.getFreeSpace() / gb;
            double freePartitionSpace1 = diskPartition1.getFreeSpace() / gb;
            double freePartitionSpace2 = diskPartition2.getFreeSpace() / gb;
            double usablePatitionSpace = diskPartition.getUsableSpace() / gb;
            System.out.println("\n**** Sizes in Giga Bytes ****\n");
            System.out.println("DISC SPACE DETAILS \n");
            //System.out.println("Total C partition size : " + totalCapacity + "GB");
            //System.out.println("Usable Space : " + usablePatitionSpace + "GB");
            System.out.println("Free Space in drive C: : " + freePartitionSpace + "GB");
            System.out.println("Free Space in drive D:  : " + freePartitionSpace1 + "GB");
            System.out.println("Free Space in drive E: " + freePartitionSpace2 + "GB");
            if(freePartitionSpace <= totalCapacity%10 || freePartitionSpace1 <= totalCapacity1%10)
            {
                System.out.println(" !!!alert!!!!");
            }
            else
                System.out.println("no alert");

            Runtime runtime;
            byte[] bytes;
            System.out.println("\n \n**MEMORY DETAILS  ** \n");
            // Print initial memory usage.
            runtime = Runtime.getRuntime();
            printUsage(runtime);

            // Allocate a 1 Megabyte and print memory usage
            bytes = new byte[1024*1024];
            printUsage(runtime);

            bytes = null;
            // Invoke garbage collector to reclaim the allocated memory.
            runtime.gc();

            // Wait 5 seconds to give garbage collector a chance to run
            try {
            Thread.sleep(5000);
            } catch(InterruptedException e) {
            e.printStackTrace();
            return;
            }

            // Total memory will probably be the same as the second printUsage call,
            // but the free memory should be about 1 Megabyte larger if garbage
            // collection kicked in.
            printUsage(runtime);
            for(int i = 0; i < 30; i++)
                     {
                         long start = System.nanoTime();
                        // log(start);
                        //number of available processors;
                         int cpuCount = ManagementFactory.getOperatingSystemMXBean().getAvailableProcessors();
                         Random random = new Random(start);
                         int seed = Math.abs(random.nextInt());
                         log("\n \n CPU USAGE DETAILS \n\n");
                         log("Starting Test with " + cpuCount + " CPUs and random number:" + seed);
                         int primes = 10000;
                         //
                         long startCPUTime = ManagementFactory.getThreadMXBean().getCurrentThreadCpuTime();
                         start = System.nanoTime();
                         while(primes != 0)
                         {
                            if(isPrime(seed))
                            {
                                primes--;
                            }
                            seed++;

                        }
                         float cpuPercent = calcCPU(startCPUTime, start, cpuCount);
                         log("CPU USAGE : " + cpuPercent + " % ");


                         try
                         {
                             Thread.sleep(1000);
                         }
                         catch (InterruptedException e) {}
        }

            try
            {
                Thread.sleep(500);
            }`enter code here`
            catch (Exception ignored) { }
        }
    }

Сделайте пакетный файл "pc.bat" as, typeperf -Sc 1 " mukit processor (_total) %% Time" Time "

Вы можете использовать класс MProcess,

/*
 *Md. Mukit Hasan
 *CSE-JU,35
 **/
import java.io.*;

общественный класс MProcessor {

public MProcessor() { String s; try { Process ps = Runtime.getRuntime().exec("Pc.bat"); BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream())); while((s = br.readLine()) != null) { System.out.println(s); } } catch( Exception ex ) { System.out.println(ex.toString()); } }

}

Затем, после некоторых манипуляций со строками, вы получаете загрузку процессора.Вы можете использовать тот же процесс для других задач.

--Мукит Хасан

Следующий код предназначен только для Linux (возможно, Unix), но он работает в реальном проекте.

    private double getAverageValueByLinux() throws InterruptedException {
    try {

        long delay = 50;
        List<Double> listValues = new ArrayList<Double>();
        for (int i = 0; i < 100; i++) {
            long cput1 = getCpuT(pattern);
            Thread.sleep(delay);
            long cput2 = getCpuT(pattern);
            double cpuproc = (1000d * (cput2 - cput1)) / (double) delay;
            listValues.add(cpuproc);
        }
        listValues.remove(0);
        listValues.remove(listValues.size() - 1);
        double sum = 0.0;
        for (Double double1 : listValues) {
            sum += double1;
        }
        return sum / listValues.size();
    } catch (Exception e) {
        e.printStackTrace();
        return 0;
    }

}

private long getCpuT(Pattern pattern) throws FileNotFoundException, IOException {
    BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));
    String line = reader.readLine();
    Matcher m = pattern.matcher(line);

    long cpuUser = 0;
    long cpuSystem = 0;
    if (m.find()) {
        cpuUser = Long.parseLong(m.group(1));
        cpuSystem = Long.parseLong(m.group(3));
    }
    return cpuUser + cpuSystem;
}

Принятый ответ в 2008 году рекомендовал SIGAR.Однако в комментарии 2014 года (@Alvaro) говорится:

Будьте осторожны при использовании Sigar, на машинах x64 возникают проблемы... Sigar 1.6.4 вылетает:EXCEPTION_ACCESS_VIOLATION И кажется, что библиотека не обновляется с 2010 года

Моя рекомендация - использовать https://github.com/oshi/oshi

Или ответ указан выше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top