Getting cpu usage in java instance, that limits in executing java virtual machine, not os.
Have a look at the java class sun.tools.jconsole.SummaryTab.java in open JDK7 or source in web.(http://www.docjar.com/html/api/sun/tools/jconsole/SummaryTab$Result.java.html)
If you know JConsole, you know that cpu usages graph. that source is below.
  354       private static class CPUOverviewPanel extends OverviewPanel {
  355           private long prevUpTime, prevProcessCpuTime;
  356   
  357           CPUOverviewPanel() {
  358               super(getText("CPU Usage"), cpuUsageKey, cpuUsageName, Plotter.Unit.PERCENT);
  359               getPlotter().setDecimals(CPU_DECIMALS);
  360           }
  361   
  362           public void updateCPUInfo(Result result) {
  363               if (prevUpTime > 0L && result.upTime > prevUpTime) {
  364                   // elapsedCpu is in ns and elapsedTime is in ms.
  365                   long elapsedCpu = result.processCpuTime - prevProcessCpuTime;
  366                   long elapsedTime = result.upTime - prevUpTime;
  367                   // cpuUsage could go higher than 100% because elapsedTime
  368                   // and elapsedCpu are not fetched simultaneously. Limit to
  369                   // 99% to avoid Plotter showing a scale from 0% to 200%.
  370                   float cpuUsage =
  371                       Math.min(99F,
  372                                elapsedCpu / (elapsedTime * 10000F * result.nCPUs));
  373   
  374                   getPlotter().addValues(result.timeStamp,
  375                                   Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS)));
  376                   getInfoLabel().setText(getText(cpuUsageFormat,
  377                                                  String.format("%."+CPU_DECIMALS+"f", cpuUsage)));
  378               }
  379               this.prevUpTime = result.upTime;
  380               this.prevProcessCpuTime = result.processCpuTime;
  381           }
  382       }
So. I made my own class to get java-cpu usage.
private void _getJavaRuntime() {
  OperatingSystemMXBean osbean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
  RuntimeMXBean runbean = (RuntimeMXBean) ManagementFactory.getRuntimeMXBean();
  int nCPUs = osbean.getAvailableProcessors();
  long prevUpTime = runbean.getUptime();
  long prevProcessCpuTime = osbean.getProcessCpuTime();
  try {
   Thread.sleep(500);
  } catch (Exception e) { }
  osbean = (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
  long upTime = runbean.getUptime();
  long processCpuTime = osbean.getProcessCpuTime();
  if (prevUpTime > 0L && upTime > prevUpTime) {
    long elapsedCpu = processCpuTime - prevProcessCpuTime;
    long elapsedTime = upTime - prevUpTime;
    javacpu = Math.min(99F, elapsedCpu / (elapsedTime * 10000F * nCPUs));
  } else {
   javacpu = 0.001;
  }
  uptime = runbean.getUptime(); 
 }
 
It should be divided by 1000F, not 10000F because as original comments says "elapsedCpu is in ns and elapsedTime is in ms". The code has 10000F there is because of the need of showing 1 decimal, and the actual cpu uages is then calculated as:
ReplyDeleteMath.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS))