使用Java获取每个核心的CPU负载

时间:2015-02-28 22:58:29

标签: java linux

我正在使用此代码使用Java代码从/ proc / stat获取CPU负载:

private static long PREV_IDLE;      //CPU Idle time
        private static long PREV_TOTAL;     //CPU Total time

public static float getCPUProcOrig() throws Exception
    {
        BufferedReader cpuReader = null;
        try
        {
            cpuReader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")));
            String cpuLine = cpuReader.readLine();
            if (cpuLine == null)
            {
                throw new Exception("/proc/stat didn't work well");
            }
            else
            {
                String[] CPU = cpuLine.split("\\s+");

                long IDLE = Long.parseLong(CPU[4]);//Get the idle CPU time.

                long DIFF_IDLE = IDLE - PREV_IDLE;
                long DIFF_TOTAL = TOTAL - PREV_TOTAL;
                long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
                //            System.out.println("CPU: " + DIFF_USAGE + "%");

                PREV_TOTAL = TOTAL;
                PREV_IDLE = IDLE;
                return (float) DIFF_USAGE;
            }
        }
        catch (Exception e)
        {
            throw e;    // It's not desirable to handle the exception here
        }
        finally
        {
            if (cpuReader != null)
                try
                {
                    cpuReader.close();
                }
                catch (IOException e)
                {
                    // Do nothing
                }
        }
    }

不幸的是,这段代码适用于平均CPU负载。我想单独列出所有核心负载。我试图扩展代码:

private static long PREV_IDLE;      //CPU Idle time
    private static long PREV_TOTAL;     //CPU Total time
    private static final int CONSERVATIVE = 0;
    private static final int AVERAGE = 1;
    private static final int OPTIMISTIC = 2;

public HashMap<String, HashMap<String, Float>> getCPUProc() throws Exception
    {
        BufferedReader cpuReader = null;
        HashMap<String, HashMap<String, Float>> usageData = new HashMap<>();

        try
        {
            String line;
            cpuReader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/stat")));
            while ((line = cpuReader.readLine()) != null)
            {
                String[] CPU = line.split("\\s+");
                if (CPU[0].startsWith("cpu"))
                {
                    String cpuName = String.valueOf(CPU[0]);//Get the cpu number.
                    long IDLE = Long.parseLong(CPU[4]);//Get the idle CPU time.
                    long TOTAL = Long.parseLong(CPU[1]) + Long.parseLong(CPU[2]) + Long.parseLong(CPU[3]) + Long.parseLong(CPU[4]);
                    //              System.out.println("IDLE : " + IDLE);

                    long DIFF_IDLE = IDLE - PREV_IDLE;
                    long DIFF_TOTAL = TOTAL - PREV_TOTAL;
                    long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
                    //            System.out.println("CPU: " + DIFF_USAGE + "%");

                    PREV_TOTAL = TOTAL;
                    PREV_IDLE = IDLE;

                    HashMap<String, Float> usageData2 = new HashMap<>();
                    usageData2.put("cpu", (float) DIFF_USAGE);

                    usageData.put(cpuName, usageData2);
                }

//                return (float) DIFF_USAGE;
            }
        }
        catch (IOException | NumberFormatException e)
        {
            throw e;    // It's not desirable to handle the exception here
        }
        finally
        {
            if (cpuReader != null)
                try
                {
                    cpuReader.close();
                }
                catch (IOException e)
                {
                    // Do nothing
                }
        }
        return usageData;
    }

从第一个代码可以看出,有几个静态变量用于计算CPU负载。 当我尝试从/ proc / stat读取所有行时,这些静态变量未正确使用,并且核心之间的数据混乱,结果不准确。

你能帮我正确阅读负载吗?我没有想法。我如何修复代码?

1 个答案:

答案 0 :(得分:4)

问题在于行:

long DIFF_IDLE = IDLE - PREV_IDLE;
long DIFF_TOTAL = TOTAL - PREV_TOTAL;
long DIFF_USAGE = DIFF_TOTAL == 0 ? 0 : (1000 * (DIFF_TOTAL - DIFF_IDLE) / DIFF_TOTAL + 5) / 10;
PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;

正如您所看到的,PREV_IDLEPREV_TOTAL在所有核心之间共享;可能你想让它们保持核心特定,所以你应该在使用它们之前加载它们。

一个好主意将是而不是

PREV_TOTAL = TOTAL;
PREV_IDLE = IDLE;

将其保存到usageData2