我想用Java监视以下系统信息:
我正在寻找一种不依赖于我自己的调用外部程序或使用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,该版本通常可用于封闭源商业产品。
按照我在这篇文章中提到的内容。我建议您使用SIGAR API。我在自己的一个应用程序中使用了SIGAR API,这很棒。您会发现它是稳定的,受良好支持的,并且充满了有用的示例。它是开源的,具有 GPL 2 strike> Apache 2.0许可证。看看这个。我感觉它将满足您的需求。
使用Java和Sigar API,您可以获得内存,CPU,磁盘,平均负载,网络接口信息和度量,进程表信息,路由信息等。
以下内容可以使您获得CPU和RAM。有关更多详细信息,请参见ManagementFactory。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| 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获取系统CPU和内存使用率。这与java.lang.management.OperatingSystemMXBean不同。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 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隐藏功能:)
1 2 3 4 5 6 7 8 9
| 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#UsingaSuninternalclass获取JVMCPU时间
要获得使用的CPU百分比,您需要做的是一些简单的数学运算:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 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,则可以在File上使用getTotalSpace和getFreeSpace方法。如果您不使用Java 6,我相信您可以使用Apache Commons IO来获得一些帮助。
我恐怕没有任何跨平台的方法来获得CPU使用率或内存使用率。
许多这些已经可以通过JMX获得。在Java 5中,JMX是内置的,它们包括JDK的JMX控制台查看器。
您可以使用JMX进行手动监视,或者如果需要在自己的运行时中从Java调用JMX命令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
| /* 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("
Total 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("
**** Sizes in Mega Bytes ****
");
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
");
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("
**** Sizes in Giga Bytes ****
");
System.out.println("DISC SPACE DETAILS
");
//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("
**MEMORY DETAILS **
");
// 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("
CPU USAGE DETAILS
");
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) { }
}
} |
以下代码仅适用于Linux(也许是Unix),但可以在实际项目中使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| 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;
} |
2008年接受的答案推荐了SIGAR。但是,作为2014年的评论(@Alvaro)说:
Be careful when using Sigar, there are problems on x64 machines...
Sigar 1.6.4 is crashing: EXCEPTION_ACCESS_VIOLATION and it seems the library
doesn't get updated since 2010
我的建议是使用https://github.com/oshi/oshi
还是上面提到的答案。
制作一个批处理文件" Pc.bat",
typeperf -sc 1" mukit processor(_Total) %% Processor Time"
您可以使用MProcess类,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| /*
*Md. Mukit Hasan
*CSE-JU,35
**/
import java.io.*;
</p>
<p>
public class MProcessor {
</p>
<wyn>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。您可以对其他任务使用相同的过程。
-穆奇特·哈桑