Frage

Ich möchte die folgenden Systeminformationen in Java überwachen:

  • Aktuelle CPU-Auslastung** (Prozent)
  • Verfügbarer Speicher* (frei/gesamt)
  • Verfügbarer Speicherplatz (frei/gesamt)

    *Beachten Sie, dass ich den Gesamtspeicher meine, der dem gesamten System zur Verfügung steht, nicht nur der JVM.

Ich suche nach einer plattformübergreifenden Lösung (Linux, Mac und Windows), die nicht darauf angewiesen ist, dass mein eigener Code externe Programme aufruft oder JNI verwendet.Obwohl dies praktikable Optionen sind, würde ich es vorziehen, den betriebssystemspezifischen Code nicht selbst zu pflegen, wenn jemand bereits eine bessere Lösung hat.

Wenn es eine kostenlose Bibliothek gibt, die dies zuverlässig und plattformübergreifend erledigt, wäre das großartig (selbst wenn sie externe Aufrufe durchführt oder selbst nativen Code verwendet).

Alle Vorschläge sind sehr willkommen.

Zur Verdeutlichung möchte ich die aktuelle CPU-Auslastung für das gesamte System erhalten, nicht nur für den/die Java-Prozess(e).

Die SIGAR-API bietet alle von mir gesuchten Funktionen in einem Paket und ist daher bisher die beste Antwort auf meine Frage.Da es jedoch unter der GPL lizenziert ist, kann ich es nicht für meinen ursprünglichen Zweck (ein kommerzielles Closed-Source-Produkt) verwenden.Es ist möglich, dass Hyperic SIGAR für die kommerzielle Nutzung lizenziert, aber ich habe mich nicht damit befasst.Für meine GPL-Projekte werde ich SIGAR in Zukunft definitiv in Betracht ziehen.

Für meine aktuellen Bedürfnisse tendiere ich zu Folgendem:

  • Für die CPU-Auslastung: OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors() (durchschnittliche Auslastung pro CPU)
  • Als Erinnerung, OperatingSystemMXBean.getTotalPhysicalMemorySize() Und OperatingSystemMXBean.getFreePhysicalMemorySize()
  • Für Speicherplatz, File.getTotalSpace() Und File.getUsableSpace()

Einschränkungen:

Der getSystemLoadAverage() und Methoden zur Abfrage des Speicherplatzes sind nur unter Java 6 verfügbar.Außerdem sind einige JMX-Funktionen möglicherweise nicht für alle Plattformen verfügbar (z. B.es wurde darüber berichtet getSystemLoadAverage() gibt unter Windows -1 zurück).

Obwohl ursprünglich unter der GPL lizenziert, ist es wurde geändert Zu Apache 2.0, die im Allgemeinen für kommerzielle Closed-Source-Produkte verwendet werden kann.

War es hilfreich?

Lösung

In Anlehnung an das, was ich erwähnt habe in diesem Beitrag.Ich empfehle Ihnen, das zu verwenden SIGAR-API.Ich verwende die SIGAR-API in einer meiner eigenen Anwendungen und sie ist großartig.Sie werden feststellen, dass es stabil ist, gut unterstützt wird und viele nützliche Beispiele enthält.Es ist Open Source mit a GPL 2 Apache 2.0-Lizenz.Hör zu.Ich habe das Gefühl, dass es Ihren Bedürfnissen gerecht wird.

Mit Java und der Sigar-API können Sie Informationen zu Speicher, CPU, Festplatte, Lastdurchschnitt, Netzwerkschnittstelleninformationen und -metriken, Prozesstabelleninformationen, Routeninformationen usw. abrufen.

Andere Tipps

Das Folgende soll Ihnen CPU und RAM bescheren.Sehen ManagementFabrik für mehr Details.

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 können Sie die CPU- und Speicherauslastung des Systems über abrufen com.sun.management.OperatingSystemMXBean.Das ist anders als 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.

Das funktioniert bei mir perfekt ohne externe API, nur mit der nativen versteckten Java-Funktion :)

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

Schauen Sie sich diesen sehr ausführlichen Artikel an:http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking#UsingaSuninternalclasstogetJVMCPUtime

Um den Prozentsatz der genutzten CPU zu ermitteln, benötigen Sie lediglich ein paar einfache Berechnungen:

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

Notiz:Sie müssen importieren com.sun.management.OperatingSystemMXBean und nicht java.lang.management.OperatingSystemMXBean.

Wenn Sie über Java 6 verfügen, können Sie als Speicherplatz Folgendes verwenden: getTotalSpace Und getFreeSpace Methoden auf Datei.Wenn Sie nicht mit Java 6 arbeiten, können Sie es meiner Meinung nach verwenden Apache Commons IO um einen Teil des Weges dorthin zu schaffen.

Ich fürchte, ich kenne keine plattformübergreifende Möglichkeit, die CPU- oder Speichernutzung zu ermitteln.

Vieles davon ist bereits über JMX verfügbar.In Java 5 ist JMX integriert und sie enthalten einen JMX-Konsolenviewer mit dem JDK.

Sie können JMX zur manuellen Überwachung verwenden oder JMX-Befehle aus Java aufrufen, wenn Sie diese Informationen in Ihrer eigenen Laufzeit benötigen.

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

Erstellen Sie eine Batch -Datei "pc.bat" as, typeperf -Sc 1 " Mukit Prozessor (_total) %% Prozessorzeit"

Sie können die Klasse MProcess verwenden,

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

öffentliche Klasse 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()); } }

}

Nach einigen String-Manipulationen erhalten Sie dann die CPU-Auslastung.Sie können den gleichen Prozess für andere Aufgaben verwenden.

--Mukit Hasan

Der folgende Code ist nur für Linux (vielleicht Unix), funktioniert aber in einem echten Projekt.

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

Die akzeptierte Antwort aus dem Jahr 2008 empfahl SIGAR.Allerdings heißt es in einem Kommentar aus dem Jahr 2014 (@Alvaro):

Seien Sie vorsichtig bei der Verwendung von Sigar, es gibt Probleme auf x64-Rechnern ... Sigar 1.6.4 stürzt ab:EXCEPTION_ACCESS_VIOLATION Und es scheint, dass die Bibliothek seit 2010 nicht aktualisiert wird

Meine Empfehlung ist die Verwendung https://github.com/oshi/oshi

Oder der oben erwähnte Antwort.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top