我正在使用Sigar在应用服务器中获取当前运行的JVM的CPU使用率,并将其存储为此数据的历史视图,但我总是获得0%的CPU百分比。
同时,我保持visualVM开放以监控CPU使用情况,并且我会看到在VisualVM中定期更改CPU%,同时使用Sigar始终报告0%。
以下是我定期运行的代码:
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%。
这种情况我做错了什么?如何让Sigar显示类似于VisualVM中显示的CPU使用率?
我尝试添加
cpu.gather(sigar, pId);
调用getProcCpu(pid)后,即使我不断增加和减少服务器上的负载,我仍然只获得两个值(0.0和9.08729312E-315)...
答案 0 :(得分:6)
我认为这取决于Sigar如何解释可用信息。可用的信息(CPU使用时间)不经常更新,ProcCpu
只是一个即时进程CPU使用信息,这就是为什么大多数ProcCpu
的CPU使用率为0的原因。从未见过它们,但对于一些ProcCpu
这个值应该远远高于100%。
您可以在一段时间内获得CPU使用率,从其开始和结束时刻分析两个ProcCpu
,将CPU使用时间和时间ProcCpu
(lastTime)考虑在内。但请记住,CPU使用时间值不会经常更新,因此可以使ProcCpu
的CPU使用时间超过秒。要获得实际的CPU使用率信息,您必须收集两个或更多ProcCpu
s。
我勾画了一个聚合和更新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
代表信息的时刻load
)是进程在某段时间内使用CPU的时间(totalDelta
)与此时段的持续时间(timeDelta
)之间的比率。虽然CPU使用时间不经常更新,但我引入了简单的启发式方法,假设负载与之前的相同,而CPU使用时间不会更新。但是假设一段时间内它可能是一个零负载,我已经引入了一个持续时间(TOTAL_TIME_UPDATE_LIMIT
),之后相同的CPU使用时间值变得合法,并且假设负载实际为零