201

我想在 Java 中监控以下系统信息:

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

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

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

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

任何建议都非常感谢。

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

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 下许可的,但它已更改Apache 2.0,它通常可用于封闭源代码的商业产品。

4

12 回答 12

68

按照我在这篇文章中提到的内容。我建议您使用SIGAR API。我在自己的一个应用程序中使用了 SIGAR API,它很棒。你会发现它很稳定,得到很好的支持,并且有很多有用的例子。它是具有GPL 2 Apache 2.0 许可证的开源软件。看看这个。我感觉它会满足你的需求。

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

于 2008-09-06T06:31:29.400 回答
58

据称,以下内容可为您提供 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
}
于 2008-09-06T02:23:07.093 回答
46

在 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.
于 2012-10-23T15:36:10.900 回答
33

这对我来说完美无缺,无需任何外部 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());
于 2014-12-03T21:30:59.177 回答
17

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

于 2010-06-22T18:04:17.910 回答
9

2008 年接受的答案推荐 SIGAR。然而,正如 2014 年的评论(@Alvaro)所说:

使用 Sigar 时要小心,x64 机器上存在问题... Sigar 1.6.4 正在崩溃:EXCEPTION_ACCESS_VIOLATION似乎该库自 2010 年以来没有更新

我的建议是使用https://github.com/oshi/oshi

或者上面提到的答案

于 2019-05-15T06:33:05.847 回答
8

对于磁盘空间,如果您有 Java 6,则可以对 File 使用getTotalSpacegetFreeSpace方法。如果您不在 Java 6 上,我相信您可以使用Apache Commons IO来获得一些方法。

恐怕我不知道有任何跨平台方式来获取 CPU 使用率或内存使用率。

于 2008-09-06T02:10:08.077 回答
6

其中很多已经可以通过 JMX 获得。在 Java 5 中,JMX 是内置的,它们包括一个带有 JDK 的 JMX 控制台查看器。

如果您在自己的运行时需要此信息,您可以使用 JMX 手动监控,或者从 Java 调用 JMX 命令。

于 2008-09-07T03:51:04.020 回答
5
/* 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) { }
        }
    }
于 2014-02-14T06:48:57.967 回答
4

以下代码仅适用于 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();
            Thread.sleep(delay);
            long cput2 = getCpuT();
            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 throws FileNotFoundException, IOException {
    BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));
    String line = reader.readLine();
    Pattern pattern = Pattern.compile("\\D+(\\d+)\\D+(\\d+)\\D+(\\d+)\\D+(\\d+)")
    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;
}
于 2009-05-07T15:04:44.850 回答
3

将批处理文件 "Pc.bat" 设为 typeperf -sc 1 "\mukit\processor(_Total)\%% Processor Time"

您可以使用 MProcess 类,

/*
 *医学博士。穆吉特哈桑
 *CSE-JU,35
 **/
导入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 使用率。您可以将相同的过程用于其他任务。

——穆基特·哈桑

于 2010-05-15T17:32:33.333 回答
0
    OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
    System.out.println((osBean.getCpuLoad() * 100) + "%");

进口com.sun.management.OperatingSystemMXBean

它仅在第二次调用后才开始工作,因此请保存 osBean 并将其置于循环中

于 2021-08-12T13:33:59.167 回答