使用Sigar API获取JVM CPU使用率

我正在使用Sigar来获取应用程序服务器中当前运行的JVM的CPU使用率,并将其存储为此数据的历史视图,但我总是获得0%的CPU百分比。

同时,我保持我的visualVM开放以监控CPU使用率,并且我看到CPU%在visualVM中定期更改,而它总是使用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)…

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

您可以在一段时间内获得CPU使用率,从其开始和结束时刻分析两个ProcCpu ,将CPU使用时间和ProcCpu (lastTime)时间考虑在内。 但请记住,CPU使用时间值不经常更新,因此可以为ProcCpu相同的CPU使用时间。 要获得实际的CPU使用率信息,您必须收集两个或更多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 )是一段时间内进程使用CPU的时间( totalDelta )与此时间段持续时间( timeDelta )之间的timeDelta

虽然CPU使用时间不经常更新,但我引入了简单的启发式方法,假设负载与之前的相同,而CPU使用时间不会更新。 但是假设一段时间内它可能是零负载,我已经引入了一个持续时间( TOTAL_TIME_UPDATE_LIMIT ),之后相同的CPU使用时间值变得合法,并且假设负载实际为零。