代码之家  ›  专栏  ›  技术社区  ›  David Crow

如何监视Java中的计算机CPU、内存和磁盘使用情况?

  •  159
  • David Crow  · 技术社区  · 17 年前

    我想监视Java中的以下系统信息:

    • 当前CPU使用率**(百分比)
    • 可用内存*(可用/总计)
    • 可用磁盘空间(可用/总计)

      *注意,我指的是整个系统可用的总内存,而不仅仅是JVM。

    我正在寻找一个跨平台的解决方案(Linux、Mac和Windows),它不依赖于我自己的代码调用外部程序或使用JNI。虽然这些都是可行的选项,但是如果有人已经有了更好的解决方案,我宁愿不自己维护操作系统特定的代码。

    如果有一个免费的库以可靠的跨平台方式完成这项工作,那就太好了(即使它进行外部调用或使用本机代码本身)。

    任何建议都非常感谢。

    为了澄清,我想得到整个系统的当前CPU使用率,而不仅仅是Java进程(ES)。

    SigarAPI在一个包中提供了我要寻找的所有功能,因此它是迄今为止我问题的最佳答案。但是,由于它是根据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授权的,但是 has been changed Apache 2.0 ,一般可用于封闭源代码的商业产品。

    10 回复  |  直到 8 年前
        1
  •  63
  •   Aravindan R    8 年前

    按照我提到的路线 in this post . 我建议你用 SIGAR API . 我在自己的一个应用程序中使用了SigarAPI,它非常棒。你会发现它是稳定的,很好的支持,并且有很多有用的例子。它是开源的 GPL 2 Apache 2.0许可证。过来看。我觉得它能满足你的需要。

    使用Java和Sigar API可以获得内存、CPU、磁盘、负载平均、网络接口信息和度量、进程表信息、路由信息等。

        2
  •  49
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    下面假设为您提供CPU和RAM。见 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
    }
    
        3
  •  32
  •   Nathan    9 年前

    在JDK1.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.
    
        4
  •  19
  •   bizzr3    11 年前

    这对我来说完全没有任何外部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());
    
        5
  •  14
  •   Nathan    9 年前

    看看这篇非常详细的文章: 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 .

        6
  •  8
  •   Matt Sheppard    17 年前

    对于磁盘空间,如果有Java 6,则可以使用 getTotalSpace getFreeSpace 方法。如果你不使用Java 6,我相信你可以使用 Apache Commons IO 去那边走走。

    恐怕我不知道任何跨平台的方法来获得CPU使用率或内存使用率。

        7
  •  5
  •   Jason Cohen    17 年前

    很多这些已经通过JMX提供了。使用Java 5,JMX是内置的,它们包含JDK的JMX控制台查看器。

    如果您需要在自己的运行时使用这些信息,可以使用JMX手动监视或调用Java中的JMX命令。

        8
  •  4
  •   AndersDJohnson    10 年前
    /* 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) { }
            }
        }
    
        9
  •  3
  •   Md. Mukit Hasan    16 年前

    将批处理文件“pc.bat”设为, typeperf-sc 1“\mukit\processor(_total)\%%处理器时间”

    您可以使用类mpprocess,

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

    public class 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的使用。您可以对其他任务使用相同的过程。

    ——Mukit Hasan

        10
  •  3
  •   Peter Mortensen Pieter Jan Bonestroo    8 年前

    下面的代码只是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;
    }