كيف يمكنني مراقبة استخدام وحدة المعالجة المركزية والذاكرة والقرص للكمبيوتر في 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, ، والتي يمكن استخدامها عمومًا للمنتجات التجارية المغلقة المصدر.

هل كانت مفيدة؟

المحلول

وعلى غرار ما ذكرته في هذا المنصب.أنصحك باستخدام واجهة برمجة تطبيقات سيجار.أستخدم SIGAR API في أحد تطبيقاتي الخاصة وهو أمر رائع.ستجد أنه مستقر ومدعوم جيدًا ومليء بالأمثلة المفيدة.وهو مفتوح المصدر مع جي بي إل 2 ترخيص أباتشي 2.0.تحقق من ذلك.لدي شعور أنه سوف يلبي احتياجاتك.

باستخدام Java وSigar API، يمكنك الحصول على معلومات ومقاييس الذاكرة ووحدة المعالجة المركزية والقرص ومتوسط ​​التحميل وواجهة الشبكة ومعلومات جدول العمليات ومعلومات المسار وما إلى ذلك.

نصائح أخرى

من المفترض أن ما يلي يحصل على وحدة المعالجة المركزية وذاكرة الوصول العشوائي.يرى ManagementFactory لمزيد من التفاصيل.

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.

هذا يعمل بالنسبة لي بشكل مثالي دون أي واجهة برمجة تطبيقات خارجية، فقط ميزة 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، فأعتقد أنه يمكنك استخدامه أباتشي كومنز آي أو للحصول على بعض الطريق هناك.

لا أعرف أي طريقة عبر الأنظمة الأساسية للحصول على استخدام وحدة المعالجة المركزية أو استخدام الذاكرة على ما أخشى.

الكثير من هذا متاح بالفعل عبر JMX.مع Java 5، يكون JMX مدمجًا ويتضمن عارض وحدة تحكم JMX مع JDK.

يمكنك استخدام 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" كـ ، typeperf -sc 1 " mukit Processor (_total) ٪٪ وقت المعالج"

يمكنك استخدام فئة MProcess،

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

معالج فئة عامة {

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

}

ثم بعد بعض التلاعب بالسلسلة، يمكنك استخدام وحدة المعالجة المركزية (CPU).يمكنك استخدام نفس العملية لمهام أخرى.

--موكيت حسن

الكود التالي هو 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 يتعطل:استثناء انتهاك وصول ويبدو أن المكتبة لا يتم تحديثها منذ عام 2010

توصيتي هي الاستخدام https://github.com/oshi/oshi

أو ال الإجابة المذكورة أعلاه.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top