如何在 Java 中监控计算机的 CPU、内存和磁盘使用情况?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I monitor the computer's CPU, memory, and disk usage in Java?
提问by David Crow
I would like to monitor the following system information in Java:
我想用Java监控以下系统信息:
- Current CPU usage** (percent)
- Available memory* (free/total)
Available disk space (free/total)
*Note that I mean overall memory available to the whole system, not just the JVM.
- 当前 CPU 使用率**(百分比)
- 可用内存*(可用/总)
可用磁盘空间(可用/总)
*请注意,我的意思是整个系统可用的总内存,而不仅仅是 JVM。
I'm looking for a cross-platform solution (Linux, Mac, and Windows) that doesn't rely on my own code calling external programs or using JNI. Although these are viable options, I would prefer not to maintain OS-specific code myself if someone already has a better solution.
我正在寻找一种跨平台解决方案(Linux、Mac 和 Windows),它不依赖于我自己的代码调用外部程序或使用 JNI。虽然这些都是可行的选择,但如果有人已经有了更好的解决方案,我宁愿不自己维护特定于操作系统的代码。
If there's a free library out there that does this in a reliable, cross-platform manner, that would be great (even if it makes external calls or uses native code itself).
如果有一个免费的库以可靠的、跨平台的方式做到这一点,那就太好了(即使它进行外部调用或使用本机代码本身)。
Any suggestions are much appreciated.
任何建议都非常感谢。
To clarify, I would like to get the current CPU usage for the whole system, not just the Java process(es).
为了澄清,我想获得整个系统的当前 CPU 使用率,而不仅仅是 Java 进程。
The SIGAR API provides all the functionality I'm looking for in one package, so it's the best answer to my question so far. However, due it being licensed under the GPL, I cannot use it for my original purpose (a closed source, commercial product). It's possible that Hyperic may license SIGAR for commercial use, but I haven't looked into it. For my GPL projects, I will definitely consider SIGAR in the future.
SIGAR API 在一个包中提供了我正在寻找的所有功能,因此它是迄今为止对我的问题的最佳答案。但是,由于它是根据 GPL 许可的,我不能将它用于我的原始目的(封闭源代码的商业产品)。Hyperic 可能会许可 SIGAR 用于商业用途,但我还没有研究过。对于我的 GPL 项目,我以后肯定会考虑 SIGAR。
For my current needs, I'm leaning towards the following:
对于我目前的需求,我倾向于以下内容:
- For CPU usage,
OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors()
(load average per cpu) - For memory,
OperatingSystemMXBean.getTotalPhysicalMemorySize()
andOperatingSystemMXBean.getFreePhysicalMemorySize()
- For disk space,
File.getTotalSpace()
andFile.getUsableSpace()
- 对于 CPU 使用率,
OperatingSystemMXBean.getSystemLoadAverage() / OperatingSystemMXBean.getAvailableProcessors()
(每个 CPU 的平均负载) - 为了记忆,
OperatingSystemMXBean.getTotalPhysicalMemorySize()
和OperatingSystemMXBean.getFreePhysicalMemorySize()
- 对于磁盘空间,
File.getTotalSpace()
以及File.getUsableSpace()
Limitations:
限制:
The getSystemLoadAverage()
and disk space querying methods are only available under Java 6. Also, some JMX functionality may not be available to all platforms (i.e. it's been reported that getSystemLoadAverage()
returns -1 on Windows).
在getSystemLoadAverage()
和磁盘空间查询方法仅可用的Java 6此外,根据一些JMX功能可能无法适用于所有平台(即它的报道,getSystemLoadAverage()
返回-1在Windows上)。
Although originally licensed under GPL, it has been changedto Apache 2.0, which can generally be used for closed source, commercial products.
虽然最初是在 GPL 下许可的,但它已更改为Apache 2.0,通常可用于封闭源代码的商业产品。
采纳答案by Matt Cummings
Along the lines of what I mentioned in this post. I recommend you use the SIGAR API. I use the SIGAR API in one of my own applications and it is great. You'll find it is stable, well supported, and full of useful examples. It is open-source with a GPL 2Apache 2.0 license. Check it out. I have a feeling it will meet your needs.
沿着我在这篇文章中提到的内容。我建议您使用SIGAR API。我在自己的一个应用程序中使用了 SIGAR API,它很棒。你会发现它很稳定,得到了很好的支持,并且充满了有用的例子。它是开源的,具有GPL 2Apache 2.0 许可证。一探究竟。我有一种感觉,它会满足您的需求。
Using Java and the Sigar API you can get Memory, CPU, Disk, Load-Average, Network Interface info and metrics, Process Table information, Route info, etc.
使用 Java 和 Sigar API,您可以获得内存、CPU、磁盘、平均负载、网络接口信息和指标、进程表信息、路由信息等。
回答by Matt Sheppard
For disk space, if you have Java 6, you can use the getTotalSpaceand getFreeSpacemethods on File. If you're not on Java 6, I believe you can use Apache Commons IOto get some of the way there.
对于磁盘空间,如果您有 Java 6,则可以在 File 上使用getTotalSpace和getFreeSpace方法。如果您不使用 Java 6,我相信您可以使用Apache Commons IO来获得一些方法。
I don't know of any cross platform way to get CPU usage or Memory usage I'm afraid.
我不知道有什么跨平台的方式来获取 CPU 使用率或内存使用率。
回答by Eugene Yokota
The following supposedly gets you CPU and RAM. See ManagementFactoryfor more details.
据说以下内容可以为您提供 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
}
回答by Jason Cohen
A lot of this is already available via JMX. With Java 5, JMX is built-in and they include a JMX console viewer with the JDK.
其中很多已经可以通过 JMX 获得。在 Java 5 中,JMX 是内置的,它们包括一个带有 JDK 的 JMX 控制台查看器。
You can use JMX to monitor manually, or invoke JMX commands from Java if you need this information in your own run-time.
如果您在自己的运行时需要此信息,您可以使用 JMX 进行手动监视,或从 Java 调用 JMX 命令。
回答by Jason Cohen
The following code is Linux (maybe Unix) only, but it works in a real project.
以下代码仅适用于 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;
}
回答by Md. Mukit Hasan
Make a batch file "Pc.bat" as, typeperf -sc 1 "\mukit\processor(_Total)\%% Processor Time"
制作一个批处理文件“Pc.bat”, typeperf -sc 1 "\mukit\processor(_Total)\%% Processor Time"
You can use the class MProcess,
您可以使用类 MProcess,
/* *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()); } }
}
}
Then after some string manipulation, you get the CPU use. You can use the same process for other tasks.
然后在一些字符串操作之后,你得到了 CPU 的使用。您可以对其他任务使用相同的流程。
--Mukit Hasan
——穆吉特·哈桑
回答by ludovicc
Have a look at this very detailled article: http://nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking#UsingaSuninternalclasstogetJVMCPUtime
看看这篇非常详细的文章:http: //nadeausoftware.com/articles/2008/03/java_tip_how_get_cpu_and_user_time_benchmarking#UsingaSuninternalclasstogetJVMCPUtime
To get the percentage of CPU used, all you need is some simple maths:
要获得 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+"%");
Note: You must import com.sun.management.OperatingSystemMXBean
and not java.lang.management.OperatingSystemMXBean
.
注意:您必须导入com.sun.management.OperatingSystemMXBean
而不是java.lang.management.OperatingSystemMXBean
.
回答by Gp2you
In JDK 1.7, you can get system CPU and memory usage via com.sun.management.OperatingSystemMXBean
. This is different than java.lang.management.OperatingSystemMXBean
.
在 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.
回答by pragati
/* 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) { }
}
}
回答by bizzr3
This works for me perfectly without any external API, just native Java hidden feature :)
这对我来说完美无缺,没有任何外部 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());