Sigar が入手可能な情報をどのように解釈するかにかかっていると思います。利用可能な情報 (CPU 使用時間) はあまり頻繁に更新されずProcCpu
、インスタント プロセスの CPU 使用率情報にすぎません。そのため、ほとんどの CPU 使用率ProcCpu
は 0 です。見たことがないものもありますが、ProcCpu
この値は 100 よりもはるかに優れているはずです。 %。
ProcCpu
CPU 使用時間とProcCpu
(lastTime) の時間を考慮して、開始と終了の瞬間から2 つの s を分析し、一定期間の CPU 使用率を取得できます。ただし、CPU 使用時間の値はあまり頻繁に更新されないことに注意してください。そのため、s に対して同じ CPU 使用時間がProcCpu
1 秒以上離れている可能性があります。実際の CPU 使用率の情報を得るには、2 つ以上ProcCpu
の を収集する必要があります。
CPU 使用率に関する情報を集約して更新するモニターをスケッチしました。
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
) は、ある期間 ( totalDelta
) とこの期間の継続時間 ( timeDelta
) の間にプロセスが CPU を使用した時間の比率です。
CPU 使用時間はそれほど頻繁には更新されませんが、CPU 使用時間は更新されませんが、負荷が以前と同じであると仮定する単純なヒューリスティックを導入しました。しかし、プロセスの負荷がしばらくゼロになる可能性があると仮定して、期間 ( TOTAL_TIME_UPDATE_LIMIT
) を導入しました。その後、同じ CPU 使用時間の値が有効になり、負荷が実際にゼロであると想定されます。