Java获得内存使用,磁盘情况
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java获得内存使用,磁盘情况相关的知识,希望对你有一定的参考价值。
参考技术Aimport java io File;
/**
*
* jdk 下的磁盘使用情况例子
*/
public class Diskfree
public static void main(String[] args)
File[] roots = File listRoots();//获取磁盘分区列表
for (File file : roots)
System out println(file getPath()+ 信息如下: );
System out println( 空闲未使用 = + file getFreeSpace()/ / / + G );//空闲空间
System out println( 已经使用 = + file getUsableSpace()/ / / + G );//可用空间
System out println( 总容量 = + file getTotalSpace()/ / / + G );//总空间
System out println();
java获得当前系统内存情况的代码如下
Java code
import java lang management ManagementFactory;
import sun management OperatingSystemMXBean;
public class OSTest
public static void main(String[] args)
OperatingSystemMXBean o *** b = (OperatingSystemMXBean) ManagementFactory getOperatingSystemMXBean();
System out println( 系统物理内存总计 + o *** b getTotalPhysicalMemorySize() / / + MB );
System out println( 系统物理可用内存总计 + o *** b getFreePhysicalMemorySize() / / + MB );
ManagementFactory getOperatingSystemMXBean()返回的是java lang management里面的OperatingSystemMXBean
我们要用的是 sun management OperatingSystemMXBean;
在java类库中可以查到
public abstract Interface sun management OperatingSystemMXBean extends java lang management OperatingSystemMXBean
所以我们可以强制转换一下
想得到磁盘使用情况的话 可以看 楼的例子 要得到系统信息的话 使用System getProperty(String key);
方法
内存使用可以使用Runtime getRuntime() getTotalMemory() Runtime getRuntime() getFreeMemory()
纯JAVA是不能同操作系统打交到得 比如你要看CPU使用率 一般就是使用JNI技术(一些简单得系统熟悉 可以通过System getProperties()获得)
lishixinzhi/Article/program/Java/hx/201311/27126
如何在 Java 中监控计算机的 CPU、内存和磁盘使用情况?
【中文标题】如何在 Java 中监控计算机的 CPU、内存和磁盘使用情况?【英文标题】:How do I monitor the computer's CPU, memory, and disk usage in Java? 【发布时间】:2010-09-08 00:16:51 【问题描述】:我想用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 下授权的,但它 has been changed 到 Apache 2.0,通常可用于闭源、商业产品。
【问题讨论】:
澄清一下,sigar api 为您获取系统信息。如果你想要 jvm 信息,请使用 JMX。 SIGAR 在 GPL 下并不妨碍您使用它,它只是意味着您必须联系作者并请求替代许可。作者通常乐于接受少量费用并允许商业许可。 由于 SIGAR 1.6.4 版本使用的是 Apache 许可证。 您知道如何获取每个处理器的负载吗? 【参考方案1】: OperatingSystemMXBean osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
System.out.println((osBean.getCpuLoad() * 100) + "%");
导入com.sun.management.OperatingSystemMXBean
它只在第二次调用后才开始工作,所以保存 osBean 并将其放入循环中
【讨论】:
【参考方案2】:在 JDK 1.7 中,您可以通过com.sun.management.OperatingSystemMXBean
获取系统 CPU 和内存使用情况。这与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.
【讨论】:
这似乎是命中注定。在 FreeBSD 10 和 OpenJDK 8 上获得 -1 的 CPU 负载。 检查这个问题***.com/q/19781087/1206998。它说需要几秒钟才能生效。 (注意:我没试过)【参考方案3】:以下代码仅适用于 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;
【讨论】:
这实际上是我一直在寻找的,但是代码缺少用于从 /proc/stat 中查找 cpu 信息的 REGEX 模式 模式是什么??【参考方案4】:2008 年接受的答案推荐 SIGAR。然而,正如 2014 年的评论 (@Alvaro) 所说:
使用 Sigar 时要小心,x64 机器上存在问题... Sigar 1.6.4 is crashing: EXCEPTION_ACCESS_VIOLATION 好像是图书馆 自 2010 年以来没有更新
我的建议是使用https://github.com/oshi/oshi
或者answer mentioned above。
【讨论】:
【参考方案5】:按照我提到的in this post。我建议您使用SIGAR API。我在自己的一个应用程序中使用了 SIGAR API,它很棒。你会发现它很稳定,得到很好的支持,并且有很多有用的例子。它是具有 GPL 2 Apache 2.0 许可证的开源软件。看看这个。我感觉它会满足您的需求。
使用 Java 和 Sigar API,您可以获得内存、CPU、磁盘、平均负载、网络接口信息和指标、进程表信息、路由信息等。
【讨论】:
使用 Sigar 时要小心,x64 机器上存在问题...***.com/questions/23405832/… 似乎该库自 2010 年以来没有更新【参考方案6】:下面的内容可能会为您提供 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
【讨论】:
上述代码的示例输出。此代码确实适用于 Java 1.5。 getCommittedVirtualMemorySize = 28622848 getFreePhysicalMemorySize = 228462592 getFreeSwapSpaceSize = 1129848832 getProcessCpuTime = 390625000 getTotalPhysicalMemorySize = 2147483647 getTotalSwapSpaceSize = 4294967295 AFAIK getProcessCpuTime = 390625000 只是该线程运行了多长时间。这对于确定处理器使用情况并不是很有用 不确定它是否真的可靠。在具有 4GB 物理内存的 Windows XP 上,它仅报告 2GB(使用 Java 6 和 Java 7 测试)。总交换大小也是错误的。 @EmmanuelBourg 只是为看到此主题的人记录,有一个与此相关的 bug。 这个方法在 Java 9 之前运行良好,现在由于 Java 正在使用新的访问检查框架,它会抛出 java.lang.reflect.InaccessibleObjectException。【参考方案7】:看看这篇非常详细的文章: 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
。
【讨论】:
这是一个非常好的答案。所有其他技术都给出了非常奇怪和不可靠的结果,但是这个带有一些尾随平均的技术对我来说就像一个魅力。 当cpu时间高于运行时间(我得到超过100%),是多线程的原因,还是怎么理解? 链接失效了,MBeanServerConnection是什么包?【参考方案8】:/* 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】:这对我来说非常适用,无需任何外部 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());
【讨论】:
老实说,我认为这是最好的答案,适用于 Linux,所以我很高兴。 任何线索为什么第二次调用显示 0.0 ?在 OpenJDK v8 上。 别忘了:“import java.lang.management.ManagementFactory;” getProcessCpuLoad 和 getSystemCpuLoad 以我的形式返回 -1。我正在使用 jdk 1.8 没有获取线程数的方法?只是想知道为什么?【参考方案10】:制作一个批处理文件“Pc.bat”为, typeperf -sc 1 "\mukit\processor(_Total)\%% 处理器时间"
你可以使用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 使用率。您可以将相同的流程用于其他任务。
--穆吉特·哈桑
【讨论】:
对我来说(Win XP)正确的命令行是:typeperf "\processor(_total)\% processor time"
如果你把它放到批处理文件中,使用 %% 而不是 %。我用technet.microsoft.com/en-us/library/bb490960.aspx。【参考方案11】:
其中很多已经可以通过 JMX 获得。在 Java 5 中,JMX 是内置的,它们包括一个带有 JDK 的 JMX 控制台查看器。
如果您在自己的运行时需要此信息,您可以使用 JMX 手动监控,或从 Java 调用 JMX 命令。
【讨论】:
【参考方案12】:对于磁盘空间,如果您有 Java 6,则可以在 File 上使用 getTotalSpace 和 getFreeSpace 方法。如果您不在 Java 6 上,我相信您可以使用 Apache Commons IO 来获得一些帮助。
恐怕我不知道任何跨平台的方法来获取 CPU 使用率或内存使用率。
【讨论】:
以上是关于Java获得内存使用,磁盘情况的主要内容,如果未能解决你的问题,请参考以下文章