3

アプリケーション サーバーで現在実行中の JVM の CPU 使用率を取得し、このデータの履歴ビュー用に保存するために Sigar を使用していますが、常に 0% の CPU パーセンテージが得られます。

その間、visualVM を開いたままにして CPU 使用率を監視しています。sigar を使用すると常に 0% と報告されますが、visualVM で定期的に CPU % が変化するのを確認できます。

定期的に実行しているコードは次のとおりです。

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% を返します。

この場合、私は何を間違っていますか?VisualVM で表示される CPU 使用率と同様の CPU 使用率を Sigar に表示させるにはどうすればよいですか?

追加してみました

cpu.gather(sigar, pId);

getProcCpu(pid) を呼び出した後、サーバーの負荷を増減し続けても、2 つの値 (0.0 と 9.08729312E-315) しか得られません...

4

1 に答える 1

6

Sigar が入手可能な情報をどのように解釈するかにかかっていると思います。利用可能な情報 (CPU 使用時間) はあまり頻繁に更新されずProcCpu、インスタント プロセスの CPU 使用率情報にすぎません。そのため、ほとんどの CPU 使用率ProcCpuは 0 です。見たことがないものもありますが、ProcCpuこの値は 100 よりもはるかに優れているはずです。 %。

ProcCpuCPU 使用時間とProcCpu(lastTime) の時間を考慮して、開始と終了の瞬間から2 つの s を分析し、一定期間の CPU 使用率を取得できます。ただし、CPU 使用時間の値はあまり頻繁に更新されないことに注意してください。そのため、s に対して同じ CPU 使用時間がProcCpu1 秒以上離れている可能性があります。実際の 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 使用時間の値が有効になり、負荷が実際にゼロであると想定されます。

于 2013-10-11T22:12:12.737 に答える