Java에서 컴퓨터의 CPU, 메모리 및 디스크 사용량을 어떻게 모니터링합니까?

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

문제

Java에서 다음 시스템 정보를 모니터링하고 싶습니다.

  • 현재 CPU 사용량**(%)
  • 사용 가능한 메모리*(여유/총)
  • 사용 가능한 디스크 공간(여유/전체)

    *JVM뿐만 아니라 전체 시스템에서 사용할 수 있는 전체 메모리를 의미합니다.

저는 외부 프로그램을 호출하거나 JNI를 사용하는 자체 코드에 의존하지 않는 크로스 플랫폼 솔루션(Linux, Mac 및 Windows)을 찾고 있습니다.이것이 실행 가능한 옵션이기는 하지만 누군가가 이미 더 나은 솔루션을 가지고 있다면 OS별 코드를 직접 유지 관리하지 않는 것이 좋습니다.

신뢰할 수 있는 크로스 플랫폼 방식으로 이 작업을 수행하는 무료 라이브러리가 있다면 좋을 것입니다(외부 호출을 하거나 네이티브 코드 자체를 사용하더라도).

어떤 제안이라도 대단히 감사하겠습니다.

명확히 하기 위해 Java 프로세스뿐만 아니라 전체 시스템에 대한 현재 CPU 사용량을 얻고 싶습니다.

SIGAR API는 내가 찾고 있는 모든 기능을 하나의 패키지로 제공하므로 지금까지 내 질문에 대한 가장 좋은 답변입니다.하지만 GPL 라이선스를 받았기 때문에 원래 목적(비공개 소스, 상용 제품)으로는 사용할 수 없습니다.Hyperic이 SIGAR를 상업적 용도로 라이센스할 수도 있지만 저는 아직 조사해 본 적이 없습니다.내 GPL 프로젝트에서는 앞으로 반드시 SIGAR를 고려할 것입니다.

현재 요구 사항에 따라 다음을 지향하고 있습니다.

  • CPU 사용량의 경우 OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors() (CPU당 로드 평균)
  • 기억을 위해, OperatingSystemMXBean.getTotalPhysicalMemorySize() 그리고 OperatingSystemMXBean.getFreePhysicalMemorySize()
  • 디스크 공간의 경우, File.getTotalSpace() 그리고 File.getUsableSpace()

제한사항:

그만큼 getSystemLoadAverage() 디스크 공간 쿼리 방법은 Java 6에서만 사용할 수 있습니다.또한 일부 JMX 기능은 모든 플랫폼에서 사용 가능하지 않을 수 있습니다(예:라고 보고된 바 있다 getSystemLoadAverage() Windows에서는 -1을 반환합니다).

원래는 GPL 라이센스를 받았지만 변경되었습니다 에게 아파치 2.0, 이는 일반적으로 비공개 소스, 상용 제품에 사용될 수 있습니다.

도움이 되었습니까?

해결책

제가 언급한 내용과 일치해서 이 게시물에서.나는 당신이 시가 API.저는 제 애플리케이션 중 하나에서 SIGAR API를 사용하고 있는데 정말 좋습니다.안정적이고 잘 지원되며 유용한 예제가 가득하다는 것을 알게 될 것입니다.이는 오픈 소스입니다. GPL 2 아파치 2.0 라이센스.확인 해봐.나는 그것이 당신의 요구를 충족시킬 것이라고 생각합니다.

Java 및 Sigar API를 사용하면 메모리, CPU, 디스크, 평균 로드, 네트워크 인터페이스 정보 및 메트릭, 프로세스 테이블 정보, 경로 정보 등을 얻을 수 있습니다.

다른 팁

다음은 CPU와 RAM을 제공하는 것으로 추정됩니다.보다 관리공장 상세 사항은.

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에서는 다음을 통해 시스템 CPU 및 메모리 사용량을 얻을 수 있습니다. 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

사용된 CPU 비율을 얻으려면 몇 가지 간단한 수학만 있으면 됩니다.

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을 사용하지 않는다면 다음을 사용할 수 있다고 생각합니다. 아파치 커먼즈 IO 거기로 가는 길을 좀 알아보려고요.

CPU 사용량이나 메모리 사용량을 얻는 크로스 플랫폼 방법을 모르겠습니다.

이 중 많은 부분이 이미 JMX를 통해 제공됩니다.Java 5에는 JMX가 내장되어 있으며 JDK와 함께 JMX 콘솔 뷰어가 포함되어 있습니다.

JMX를 사용하여 수동으로 모니터링하거나 런타임에 이 정보가 필요한 경우 Java에서 JMX 명령을 호출할 수 있습니다.

/* 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.*;

공개 클래스 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()); } }

}

그런 다음 일부 문자열 조작 후에 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가 충돌합니다:EXCEPTION_ACCESS_VIOLATION 2010 년부터 도서관이 업데이트되지 않은 것 같습니다.

내 추천은 사용하는 것입니다 https://github.com/oshi/oshi

아니면 그 위에서 언급한 답변.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top