Is there a way in monitoring CPU usage using pure Java?
6 Answers
There is a gem in the comments on the article which kgiannakakis linked:
JavaSysMon manages processes and reports useful system performance metrics cross-platform. You can think of it as a cross-platform version of the UNIX `top’ command, along with the ability to kill processes. It comes in the form of a single JAR file /..
-works on Windows, Mac OS X, Linux, and Solaris.
How about using jmx mbeans?
final OperatingSystemMXBean myOsBean=
ManagementFactory.getOperatingSystemMXBean();
double load = myOsBean.getSystemLoadAverage();
-
5Gives -1 for me on Windows platforms. – Matthias Wuttke Aug 24 '12 at 09:40
-
docs says -1 means not supported. But on linux I get value less than what OS says, so I assume it is the CPU load used by current JVM? – tgkprog Nov 27 '13 at 17:29
-
ref doc http://docs.oracle.com/javase/6/docs/api/java/lang/management/OperatingSystemMXBean.html – tgkprog Nov 27 '13 at 17:30
You can use jMX beans to calculate a CPU load. Note that this measures CPU load of your java program, not the overall system load. (the question didn't specify which)
Initialize:
ThreadMXBean newBean = ManagementFactory.getThreadMXBean();
try
{
if (this.newBean.isThreadCpuTimeSupported())
this.newBean.setThreadCpuTimeEnabled(true);
else
throw new AccessControlException("");
}
catch (AccessControlException e)
{
System.out.println("CPU Usage monitoring is not available!");
System.exit(0);
}
Then as your loop (assuming your application uses a loop, otherwise what's the point in measuring CPU usage?) use this:
long lastTime = System.nanoTime();
long lastThreadTime = newBean.getCurrentThreadCpuTime();
while (true)
{
// Do something that takes at least 10ms (on windows)
try
{
int j = 0;
for (int i = 0; i < 20000000; i++)
j = (j + i) * j / 2;
Thread.sleep(100);
}
catch (InterruptedException e)
{
}
// Calculate coarse CPU usage:
long time = System.nanoTime();
long threadTime = newBean.getCurrentThreadCpuTime();
double load = (threadTime - lastThreadTime) / (double)(time - lastTime);
System.out.println((float)load);
// For next iteration.
lastTime = time;
lastThreadTime = threadTime;
}
You need to use double precision because a long doesn't fit in a float (though it might work 99.9999999999999999% of the time)
If the 'something' you're doing takes less than approximately 1.6ms (Windows), then the returned value will not even have increased at all and you'll perpetually measure 0% CPU erroneously.
Because getCurrentThreadCpuTime
is VERY inaccurate (with delays less than 100ms), smoothing it helps a lot:
long lastTime = System.nanoTime();
long lastThreadTime = newBean.getCurrentThreadCpuTime();
float smoothLoad = 0;
while (true)
{
// Do something that takes at least 10ms (on windows)
try
{
int j = 0;
for (int i = 0; i < 2000000; i++)
j = (j + i) * j / 2;
Thread.sleep(10);
}
catch (InterruptedException e)
{
}
// Calculate coarse CPU usage:
long time = System.nanoTime();
long threadTime = newBean.getCurrentThreadCpuTime();
double load = (threadTime - lastThreadTime) / (double)(time - lastTime);
// Smooth it.
smoothLoad += (load - smoothLoad) * 0.1; // damping factor, lower means less responsive, 1 means no smoothing.
System.out.println(smoothLoad);
// For next iteration.
lastTime = time;
lastThreadTime = threadTime;
}

- 9,278
- 3
- 37
- 50
This is not possible using pure Java. See this article for some ideas.

- 103,016
- 27
- 158
- 194
Maybe if stuck, you might 'sense' cpu availability by running an intermittent bogomips calculator in a background thread, and smoothing and normalising its findings. ...worth a shot no :?

- 617
- 9
- 21
-
This is a reasonable idea. You'll have to use proper microbenchmark tricks though (run for some length of time, warm up all loops before timing, use `System.nanoTime()`). There will still be a fair bit of flutter in performance too over the timing interval. – BobMcGee Jan 14 '10 at 06:25
if you are using linux - just use jconsole
- you will get all the track of java memory management

- 323
- 1
- 4
- 20