【问题标题】:Get CPU load per core using Java使用 Java 获取每个内核的 CPU 负载
【发布时间】:2015-05-01 12:22:12
【问题描述】:

我正在使用此代码使用 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 读取所有行时,这些静态变量没有正确使用,核心之间的数据混乱,结果不准确。

你能帮我正确阅读负载吗?我没主意了。如何修复代码?

【问题讨论】:

    标签: java linux


    【解决方案1】:

    问题在于行:

    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_IDLE 和 PREV_TOTAL 在所有内核之间共享;可能你想让它们保持特定于核心,所以你应该在使用它们之前加载这些值。

    一个好主意是代替

    PREV_TOTAL = TOTAL;
    PREV_IDLE = IDLE;
    

    将它们保存到usageData2

    【讨论】:

    • 是的,这正是问题所在。我该如何解决?
    • 查看编辑以获取有关如何依赖核心存储值的建议。您已经按核心保存了“DIFF_USAGE”,所以我假设您拥有自己编写代码的所有工具和建议。请注意在第一次迭代时地图中仍然没有任何“TOTAL”和“IDLE”值,如果处理不当,NullException 可能会上升
    • 能否请您粘贴完整的示例?
    猜你喜欢
    • 2011-02-25
    • 2021-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 2011-04-10
    • 1970-01-01
    相关资源
    最近更新 更多