Domanda

Vorrei monitorare le seguenti informazioni di sistema in Java:

  • Utilizzo attuale della CPU** (percentuale)
  • Memoria disponibile* (libera/totale)
  • Spazio su disco disponibile (libero/totale)

    *Nota che intendo la memoria complessiva disponibile per l'intero sistema, non solo per la JVM.

Sto cercando una soluzione multipiattaforma (Linux, Mac e Windows) che non si basi sul mio codice che chiama programmi esterni o utilizza JNI.Sebbene queste siano opzioni praticabili, preferirei non mantenere personalmente il codice specifico del sistema operativo se qualcuno ha già una soluzione migliore.

Se esistesse una libreria gratuita che lo facesse in modo affidabile e multipiattaforma, sarebbe fantastico (anche se effettua chiamate esterne o utilizza il codice nativo stesso).

Tutti i suggerimenti sono molto apprezzati.

Per chiarire, vorrei ottenere l'utilizzo corrente della CPU per l'intero sistema, non solo per i processi Java.

L'API SIGAR fornisce tutte le funzionalità che cerco in un unico pacchetto, quindi finora è la migliore risposta alla mia domanda.Tuttavia, poiché è concesso in licenza sotto GPL, non posso utilizzarlo per il mio scopo originale (un prodotto commerciale, a sorgente chiuso).È possibile che Hyperic possa concedere in licenza SIGAR per uso commerciale, ma non ho approfondito la questione.Per i miei progetti GPL prenderò sicuramente in considerazione SIGAR in futuro.

Per le mie esigenze attuali, mi sto orientando verso quanto segue:

  • Per l'utilizzo della CPU, OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors() (carico medio per CPU)
  • Per memoria, OperatingSystemMXBean.getTotalPhysicalMemorySize() E OperatingSystemMXBean.getFreePhysicalMemorySize()
  • Per lo spazio su disco, File.getTotalSpace() E File.getUsableSpace()

Limitazioni:

IL getSystemLoadAverage() e i metodi di interrogazione dello spazio su disco sono disponibili solo in Java 6.Inoltre, alcune funzionalità JMX potrebbero non essere disponibili per tutte le piattaforme (ad es.è stato riferito che getSystemLoadAverage() restituisce -1 su Windows).

Sebbene originariamente concesso in licenza sotto GPL, it è stato cambiato A Apache 2.0, che generalmente può essere utilizzato per prodotti commerciali a codice chiuso.

È stato utile?

Soluzione

Sulla falsariga di quanto ho detto in questo articolo.Ti consiglio di utilizzare il API SIGAR.Utilizzo l'API SIGAR in una delle mie applicazioni ed è fantastico.Scoprirai che è stabile, ben supportato e pieno di esempi utili.È open source con a GPL2 Licenza Apache 2.0.Controlla.Ho la sensazione che soddisferà le tue esigenze.

Utilizzando Java e l'API Sigar è possibile ottenere informazioni e metriche su memoria, CPU, disco, media del carico, interfaccia di rete, informazioni sulla tabella dei processi, informazioni sul percorso, ecc.

Altri suggerimenti

Quanto segue presumibilmente ti dà CPU e RAM.Vedere GestioneFabbrica per ulteriori dettagli.

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
}

In JDK 1.7, puoi ottenere l'utilizzo della CPU e della memoria del sistema tramite com.sun.management.OperatingSystemMXBean.Questo è diverso da 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.

Funziona perfettamente per me senza alcuna API esterna, solo funzionalità nascoste Java native :)

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());

Dai un'occhiata a questo articolo molto dettagliato:http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking#UsingaSuninternalclasstogetJVMCPUtime

Per ottenere la percentuale di CPU utilizzata, tutto ciò di cui hai bisogno sono alcuni semplici calcoli:

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+"%");

Nota:Devi importare com.sun.management.OperatingSystemMXBean e non java.lang.management.OperatingSystemMXBean.

Per lo spazio su disco, se hai Java 6, puoi utilizzare il file getTotalSpace E getFreeSpace metodi su file.Se non sei su Java 6, credo che tu possa usare Apache CommonsIO per arrivare in qualche modo lì.

Temo che non conosco alcun modo multipiattaforma per ottenere l'utilizzo della CPU o l'utilizzo della memoria.

Molto di questo è già disponibile tramite JMX.Con Java 5, JMX è integrato e includono un visualizzatore di console JMX con JDK.

È possibile utilizzare JMX per monitorare manualmente oppure richiamare comandi JMX da Java se sono necessarie queste informazioni durante il runtime.

/* 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) { }
        }
    }

Crea un file batch "pc.bat" as, typeperf -sc 1 " mukit processor (_total) %% Tempo del processore"

Puoi usare la classe MProcess,

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

classe pubblica 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()); } }

}

Quindi, dopo un po' di manipolazione delle stringhe, ottieni l'utilizzo della CPU.È possibile utilizzare lo stesso processo per altre attività.

--Mukit Hasan

Il seguente codice è solo Linux (forse Unix), ma funziona in un progetto reale.

    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;
}

La risposta accettata nel 2008 raccomandava SIGAR.Tuttavia, come dice un commento del 2014 (@Alvaro):

Fai attenzione quando usi Sigar, ci sono problemi sulle macchine x64... Sigar 1.6.4 si blocca:ECCEZIONE CAUSATA DA UNA VIOLAZIONE D'ACCESSO E sembra che la biblioteca non venga aggiornata dal 2010

La mia raccomandazione è di usare https://github.com/oshi/oshi

O il risposta menzionata sopra.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top