【问题标题】:Get memory and CPU usage获取内存和 CPU 使用率
【发布时间】:2011-09-11 04:19:26
【问题描述】:

我想获取总物理内存、CPU 使用率以及正在使用的内存量。我查看了Runtime.freeMemory(),但这不是整个系统的可用内存。

【问题讨论】:

标签: java cpu-usage memory-footprint


【解决方案1】:

我知道我的答案迟到了,但我认为这段代码很有趣。 这是对“封闭”代码的改编,在直接应用之前应该修改:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.lang.Process;
import java.lang.Runtime;
import java.util.HashMap;

/**
 * SystemStatusReader is a collection of methods to read system status (cpu and memory)
 * 
 * @author Andreu Correa Casablanca
 */
public class SystemStatusReader
{
    public static final int CONSERVATIVE    = 0;
    public static final int AVERAGE     = 1;
    public static final int OPTIMISTIC  = 2;

    /**
     * cpuUsage gives us the percentage of cpu usage
     * 
     * mpstat -P ALL out stream example:
     *
     *  Linux 3.2.0-30-generic (castarco-laptop)    10/09/12    _x86_64_    (2 CPU)                 - To discard
     *                                                                                              - To discard
     *  00:16:30     CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle    - To discard
     *  00:16:30     all   17,62    0,03    3,55    0,84    0,00    0,03    0,00    0,00   77,93
     *  00:16:30       0   17,36    0,05    3,61    0,83    0,00    0,05    0,00    0,00   78,12
     *  00:16:30       1   17,88    0,02    3,49    0,86    0,00    0,01    0,00    0,00   77,74
     * 
     * @param measureMode Indicates if we want optimistic, convervative or average measurements.
     */
    public static Double cpuUsage (int measureMode) throws Exception {

        BufferedReader mpstatReader = null;

        String      mpstatLine;
        String[]    mpstatChunkedLine;

        Double      selected_idle;

        try {
            Runtime runtime = Runtime.getRuntime();
            Process mpstatProcess = runtime.exec("mpstat -P ALL");

            mpstatReader = new BufferedReader(new InputStreamReader(mpstatProcess.getInputStream()));

            // We discard the three first lines
            mpstatReader.readLine();
            mpstatReader.readLine();
            mpstatReader.readLine();

            mpstatLine = mpstatReader.readLine();
            if (mpstatLine == null) {
                throw new Exception("mpstat didn't work well");
            } else if (measureMode == SystemStatusReader.AVERAGE) {
                mpstatChunkedLine = mpstatLine.replaceAll(",", ".").split("\\s+");
                selected_idle = Double.parseDouble(mpstatChunkedLine[10]);
            } else {
                selected_idle   = (measureMode == SystemStatusReader.CONSERVATIVE)?200.:0.;
                Double candidate_idle;

                int i = 0;
                while((mpstatLine = mpstatReader.readLine()) != null) {
                    mpstatChunkedLine = mpstatLine.replaceAll(",", ".").split("\\s+");
                    candidate_idle = Double.parseDouble(mpstatChunkedLine[10]);

                    if (measureMode == SystemStatusReader.CONSERVATIVE) {
                        selected_idle = (selected_idle < candidate_idle)?selected_idle:candidate_idle;
                    } else if (measureMode == SystemStatusReader.OPTIMISTIC) {
                        selected_idle = (selected_idle > candidate_idle)?selected_idle:candidate_idle;
                    }
                    ++i;
                }
                if (i == 0) {
                    throw new Exception("mpstat didn't work well");
                }
            }
        } catch (Exception e) {
            throw e; // It's not desirable to handle the exception here
        } finally {
            if (mpstatReader != null) try {
                mpstatReader.close();
            } catch (IOException e) {
                // Do nothing
            }
        }

        return  100-selected_idle;
    }

    /**
     * memoryUsage gives us data about memory usage (RAM and SWAP)
     */
    public static HashMap<String, Integer> memoryUsage () throws Exception {
        BufferedReader freeReader = null;

        String      freeLine;
        String[]    freeChunkedLine;

        HashMap<String, Integer> usageData = new HashMap<String, Integer>();

        try {
            Runtime runtime = Runtime.getRuntime();
            Process freeProcess = runtime.exec("free -k"); // We measure memory in kilobytes to obtain a greater granularity

            freeReader = new BufferedReader(new InputStreamReader(freeProcess.getInputStream()));

            // We discard the first line
            freeReader.readLine();

            freeLine = freeReader.readLine();
            if (freeLine == null) {
                throw new Exception("free didn't work well");
            }
            freeChunkedLine = freeLine.split("\\s+");

            usageData.put("total", Integer.parseInt(freeChunkedLine[1]));

            freeLine = freeReader.readLine();
            if (freeLine == null) {
                throw new Exception("free didn't work well");
            }
            freeChunkedLine = freeLine.split("\\s+");

            usageData.put("used", Integer.parseInt(freeChunkedLine[2]));

            freeLine = freeReader.readLine();
            if (freeLine == null) {
                throw new Exception("free didn't work well");
            }
            freeChunkedLine = freeLine.split("\\s+");

            usageData.put("swap_total", Integer.parseInt(freeChunkedLine[1]));
            usageData.put("swap_used", Integer.parseInt(freeChunkedLine[2]));
        } catch (Exception e) {
            throw e;
        } finally {
            if (freeReader != null) try {
                freeReader.close();
            } catch (IOException e) {
                // Do nothing
            }
        }

        return usageData;
    }
}

【讨论】:

  • 这仅适用于 *nix 系统,不适用于 Windows。
【解决方案2】:

您可以使用 SIGAR (http://support.hyperic.com/display/SIGAR/Home)。我相信这是跨平台的(我只在 Windows 上尝试过)并且我知道它可以工作(因为我已经尝试过了)。

Javadoc:http://www.hyperic.com/support/docs/sigar/

二进制文件:http://support.hyperic.com/display/SIGAR/Home#Home-binaries

【讨论】:

  • javadoc 与二进制文件不匹配。我似乎在我下载的 JAR 文件中找不到 CpuPerc 类。
  • @TheDoctor Weird。我不知道出了什么问题。这些链接似乎仍然是最新的。我知道他们必须使用本机代码,所以也许您的操作系统没有与 SIGAR 的接口?我建议仔细检查一些小事——你是最新版本吗?你有正确的进口吗?等等。
【解决方案3】:

MemoryCPU

CPU 示例:

static final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();
      ...

    long start = threadBean.getCurrentThreadCpuTime();
     for (int i = 0; i < 10000000; i++) {
        ...
     }
    long finish = threadBean.getCurrentThreadCpuTime();

【讨论】:

    【解决方案4】:

    在 Linux 上,您可以将 /proc/meminfo 作为文本文件打开并解析结果。

    【讨论】:

    • 我需要一个跨平台的解决方案
    【解决方案5】:

    通过“jconsole”使用 JMX,如果这用于交互使用。它显示漂亮的实时图表,以及许多其他诊断信息。

    【讨论】:

    • 您能告诉我们JMX用来获取内存信息的Java库和方法是什么,以及在我们自己的程序中,我们如何以与JVisualVM或Jconsole.exe相同的方式使用这些方法有吗?
    • 我假设 JConsole 等人只是通过 TCP 端口使用常规 JMX 访问;而JVM本身暴露了很多JMX属性。
    猜你喜欢
    • 1970-01-01
    • 2014-03-25
    • 2021-02-27
    • 1970-01-01
    • 1970-01-01
    • 2014-05-07
    • 2022-07-26
    • 2018-03-17
    • 2015-07-22
    相关资源
    最近更新 更多