Java: Debugging 100% or more CPU usage

Please also note that in a virtual machine the CPU usage can exceed the maximum value you’d expect: we had a virtual machine with 2 virtual CPUs and our java process often went over 300% CPU load in top under heavy load.

First to find out the PID of your java process you can use either jps or just the normal ps command. For example to find the process ID of a JBoss server, you can use:

# $JAVA_HOME/bin/jps -v | grep JBOSS | awk '{ print $1; }'
20050

or:

# ps aux | grep JBOSS | grep -v grep | awk '{ print $2; }'
20050

Now, top does show that you have a very high CPU load but you don’t see where exactly it happens. It’d be helpful see which threads are consuming the most CPU. This can be done with the -H option:

# top -Hp 20050

This shows a per-thread breakdown of the CPU usage. The column PID in the top output shows the thread ID.

If you notice any Thread with a CPU usage higher than the others, note it down and check what’s its stack trace using jstack:

# $JAVA_HOME/bin/jstack 20050

This will display a list of all threads in process 20050 as well as their stacktraces. If you get the following message:

20050: Unable to open socket file: target process not responding or HotSpot VM not loaded
The -F option can be used when the target process is not responding

Use the -F (as suggested by jstack):

# $JAVA_HOME/bin/jstack -F 20050

Now search for the thread with a high CPU consumption in the file. It will show a state (e.g. BLOCKED, IN_JAVA, IN_NATIVE…) and is followed by a StackTrace if possible or by the message:

Error occurred during stack walking

From there on, you can analyze the stack trace and figure out what may be the cause of the high CPU load.

Leave a Reply

Your email address will not be published. Required fields are marked *