Newsletter sign-up
View all newsletters

Sign up for our Enterprise Java Newsletter

Enterprise Java

Profiling CPU usage from within a Java application

Roll your own CPU usage monitor using simple JNI

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone

November 8, 2002

Q How do you determine CPU usage in Java?

A So, here is the good news and the bad news. The bad news is that programmatically querying for CPU usage is impossible using pure Java. There is simply no API for this. A suggested alternative might use Runtime.exec() to determine the JVM's process ID (PID), call an external, platform-specific command like ps, and parse its output for the PID of interest. But, this approach is fragile at best.

The good news, however, is that a reliable solution can be accomplished by stepping outside Java and writing a few C code lines that integrate with the Java application via Java Native Interface (JNI). I show below how easy it is by creating a simple JNI library for the Win32 platform. The Resources section contains a link to the library you can customize for your own needs and port to other platforms.

In general, JNI is somewhat complex to use. However, when you call in one direction only—from Java into native code—and communicate using primitive data types, things remain simple. There are many good references (see Resources) on JNI, so I do not provide a JNI tutorial here; I merely outline my implementation steps.

I begin by creating a class com.vladium.utils.SystemInformation that declares a native method, which returns the number of milliseconds of CPU time used by the current process so far:

         public static native long getProcessCPUTime ();


I use the javah tool from the JDK to produce the following C header for my future native implementation:

JNIEXPORT jlong JNICALL
Java_com_vladium_utils_SystemInformation_getProcessCPUTime (JNIEnv * env, jclass cls)


On most Win32 platforms, this method can be implemented using the GetProcessTimes() system call and is literally three lines of C code:

JNIEXPORT jlong JNICALL
Java_com_vladium_utils_SystemInformation_getProcessCPUTime (JNIEnv * env, jclass cls)
{
    FILETIME creationTime, exitTime, kernelTime, userTime;
    
    GetProcessTimes (s_currentProcess, & creationTime, & exitTime, & kernelTime, & userTime);
    return (jlong) ((fileTimeToInt64 (& kernelTime) + fileTimeToInt64 (& userTime)) /
        (s_numberOfProcessors * 10000));
}


This method adds CPU time spent executing kernel and user code on behalf of the current process, normalizes it by the number of processors, and converts the result to milliseconds. The fileTimeToInt64() is a helper function that converts the FILETIME structure to a 64-bit integer, and s_currentProcess and s_numberOfProcessors are global variables that can be conveniently initialized in a JNI method that's called once when the JVM loads the native library:

static HANDLE s_currentProcess;
static int s_numberOfProcessors;
JNIEXPORT jint JNICALL
JNI_OnLoad (JavaVM * vm, void * reserved)
{
    SYSTEM_INFO systemInfo;
        
    s_currentProcess = GetCurrentProcess ();
    GetSystemInfo (& systemInfo);
    s_numberOfProcessors = systemInfo.dwNumberOfProcessors;
    return JNI_VERSION_1_2;
}


Note that if you implement getProcessCPUTime() on a Unix platform, you would likely use the getrusage system call as your starting point.

  • Digg
  • Reddit
  • SlashDot
  • Stumble
  • del.icio.us
  • Technorati
  • dzone
Comments (6)
Login
Forgot your account info?

BSD-licensed cross-platform libraryBy jezhumble on December 19, 2009, 12:00 pmI wrote a library that does this, distributed as a single jar, with all the native code embedded. It currently works on Linux, Windows and Mac OS X. Support for...

Reply | Read entire comment

ThanksBy Anonymous on October 23, 2009, 2:27 amReally its good article.. Thank you so much..!!

Reply | Read entire comment

ThanksBy Anonymous on July 27, 2009, 7:45 amCool Article

Reply | Read entire comment

helpBy Anonymous on June 4, 2009, 8:31 pmthis is a great article. no where else on the web had something as in depth. I'm an intern developing Java and utilizing this code would help me out with my project...

Reply | Read entire comment

Good ArticleBy Anonymous on February 20, 2009, 6:59 amGood Article

Reply | Read entire comment

View all comments

Add comment
Anonymous comments subject to approval. Register here for member benefits.
Have a JavaWorld account? Log in here. Register now for a free account.
Resources