使用 Sigar API 获取 JVM CPU 使用率

Using Sigar API to get JVM CPU usage(使用 Sigar API 获取 JVM CPU 使用率)

本文介绍了使用 Sigar API 获取 JVM CPU 使用率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Sigar 获取应用程序服务器中当前运行的 JVM 的 CPU 使用率并将其存储以供历史查看此数据,但我总是得到 0% 的 CPU 百分比.

I'm using Sigar to get the CPU usage of the current running JVM in an application server and store it for historical view of this data, but I always get 0% CPU percentage.

同时,我打开我的 visualVM 以监控 CPU 使用情况,我可以看到 VisualVM 中的 CPU % 定期变化,而它总是使用 Sigar 报告 0%.

In the meanwhile, I keep my visualVM open to monitor CPU usage, and I get to see the CPU % changing periodically in visualVM while it always reports 0% using Sigar.

这是我定期运行的代码:

Here is the code I m running periodically:

Sigar sigar = new Sigar();
ProcCpu cpu = null;
long pId = sigar.getPid(); // This one gives me the same process ID that I see in visualVM
try {
    cpu = sigar.getProcCpu(pId);

} 
catch (SigarException se) {
    se.printStackTrace();
}
System.out.print(cpu.getPercent());

此代码始终给出 0%.

This code always gives 0%.

在这种情况下我做错了什么?如何让 Sigar 显示类似于 VisualVM 中显示的 CPU 使用率?

What am I doing wrong it this case? How can I get Sigar to display CPU usage similar to the usage displayed in VisualVM?

我尝试添加

cpu.gather(sigar, pId);

在调用 getProcCpu(pid) 之后,即使我不断增加和减少服务器上的负载,我也只能得到两个值(0.0 和 9.08729312E-315)...

after calling getProcCpu(pid), but I keep getting only two values (0.0 and 9.08729312E-315) even if I keep increasing and decreasing load on the server...

推荐答案

我认为这取决于 Sigar 如何解释可用信息.它可用的信息(CPU 使用时间)更新不是很频繁,而 ProcCpu 只是一个即时进程 CPU 使用信息,这就是为什么大多数 ProcCpu 的 CPU 使用率为 0.从未见过,但对于某些 ProcCpu,这个值应该大大优于 100%.

I think that it depends on how Sigar interprets available information. Information available to it (CPU usage time) updates not very often, and ProcCpu is just an instant process CPU usage information, that is why CPU usage for most ProcCpu is 0. Never seen them, but for some ProcCpu this value should be be vastly superior to 100%.

你可以得到一段时间的CPU使用率,分析两个ProcCpu的开始和结束时刻,获取CPU使用时间和ProcCpu的时间(lastTime) 考虑在内.但请记住,CPU 使用时间值不会经常更新,因此 ProcCpu 的相同 CPU 使用时间可能会超过一秒.要获得实际的 CPU 使用信息,您必须收集两个或多个 ProcCpu.

You could get CPU usage for some period, analysing two ProcCpus from the start and the end moments of it, taking CPU usage time and time of ProcCpu (lastTime) into account. But remember, that CPU usage time value updates not very often, so it is possible to get the same CPU usage time for ProcCpus more than second apart. To have actual CPU usage information, you have to collect two or more ProcCpus.

我绘制了一个监控器,用于汇总和更新有关 CPU 使用率的信息:

I'v sketched a monitor that aggregates and updates information on CPU usage:

import java.util.Timer;
import java.util.TimerTask;
import org.hyperic.sigar.ProcCpu;
import org.hyperic.sigar.Sigar;

class SigarLoadMonitor {

    private static final int TOTAL_TIME_UPDATE_LIMIT = 2000;

    private final Sigar sigar;
    private final int cpuCount;
    private final long pid;
    private ProcCpu prevPc;
    private double load;

    private TimerTask updateLoadTask = new TimerTask() {
        @Override public void run() {
            try {
                ProcCpu curPc = sigar.getProcCpu(pid);
                long totalDelta = curPc.getTotal() - prevPc.getTotal();
                long timeDelta = curPc.getLastTime() - prevPc.getLastTime();
                if (totalDelta == 0) {
                    if (timeDelta > TOTAL_TIME_UPDATE_LIMIT) load = 0;
                    if (load == 0) prevPc = curPc;
                } else {
                    load = 100. * totalDelta / timeDelta / cpuCount;
                    prevPc = curPc;
                }
            } catch (SigarException ex) {
                throw new RuntimeException(ex);
            }
        }
    };

    public SigarLoadMonitor() throws SigarException {
        sigar = new Sigar();
        cpuCount = sigar.getCpuList().length;
        pid = sigar.getPid();
        prevPc = sigar.getProcCpu(pid);
        load = 0;
        new Timer(true).schedule(updateLoadTask, 0, 1000);
    }

    public double getLoad() {
        return load;
    }
}

  • ProcCpu — 进程信息的即时 CPU 使用率
  • curPc.getTotal() — 进程使用 CPU 的总时间
  • curPc.getLastTime()ProcCpu 代表信息的时刻
  • CPU 使用率 (load) 是进程在某个时间段内使用 CPU 的时间 (totalDelta) 与该时间段的持续时间 (timeDelta) 的比率).
    • ProcCpu — instant CPU usage by process information
    • curPc.getTotal() — total time that process used CPU
    • curPc.getLastTime() — moment for which ProcCpu represents information
    • CPU usage (load) is a ratio of time that process used CPU during some period (totalDelta) and this period's duration (timeDelta).
    • 虽然 CPU 使用时间不经常更新,但我引入了简单的启发式方法,假设负载与以前相同,而 CPU 使用时间不更新.但是假设它可能在一段时间内为零负载,我引入了一个持续时间(TOTAL_TIME_UPDATE_LIMIT),之后相同的CPU使用时间值变得合法,并且假设负载真的是零.

      While CPU usage time updates not very often, I've introdused simple heuristic, that supposes that the load is the same as previous, while CPU usage time doesn't update. But supposing that it could be zero load for a process for some time, I've introdused a duration (TOTAL_TIME_UPDATE_LIMIT), after which the same CPU usage time value become legal, and it is supposed that the load is really zero.

      这篇关于使用 Sigar API 获取 JVM CPU 使用率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:使用 Sigar API 获取 JVM CPU 使用率

基础教程推荐