Java获得内存使用,磁盘情况

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java获得内存使用,磁盘情况相关的知识,希望对你有一定的参考价值。

参考技术A

  import 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获得内存使用,磁盘情况的主要内容,如果未能解决你的问题,请参考以下文章

Java:是不是存在磁盘与内存一样快的情况?

java如何获取系统内存、cpu等信息。

在Java中将sqlite从磁盘备份和恢复到内存

libvirt-java怎么获得kvm虚拟机内存使用率

libvirt-java怎么获得kvm虚拟机内存使用率

Centos下查看cpu磁盘内存使用情况以及如何清理内存