Using Sigar API to get JVM CPU usage

 ̄綄美尐妖づ 提交于 2019-11-29 05:16:19

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%.

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.


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 — 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).

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!