views:

596

answers:

3

Hello,

I'm running a multithreaded java app in Linux RedHat 5.3 on a machine that has 8 cores (2 quad-core cpu's).

I want to monitor the cpu usage of each thread, preferably relative to the maximal cpu it can get (a single thread running on 1 of the cores should go up to 100% and not 12.5%).

Can I do it with jconsole/visualVM? Is there another (hopefully free) tool?

Yoav

+2  A: 

You can infer from stat files in /proc/PID/ and /proc/PID/task/PID/. Problem is that lots of threads are generally created (maybe not with your app?) and those task files will come and go. The parent PID should however should report the user/kernel times in total scheduled time on all procs and thus compared against wallclock should give you a good start.

Xepoch
+1  A: 

If you don't want to use OS specific functions like traversing the /proc directory, you can usually get the values you're looking for from the Java management interface with ThreadMXBean.getThreadCpuTime() and ThreadMXBean.getThreadUserTime().

jarnbjo
+1  A: 

As jarnbjo answered, you can query the Thread management JMX Bean for the thread's cpu and user time:

import static org.junit.Assert.assertTrue;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

import org.junit.Test;

public class ThreadStatsTest {

 @Test
 public void testThreadStats() throws Exception {
  ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
  assertTrue(threadMXBean.isThreadCpuTimeSupported());
  assertTrue(threadMXBean.isCurrentThreadCpuTimeSupported());

  threadMXBean.setThreadContentionMonitoringEnabled(true);
  threadMXBean.setThreadCpuTimeEnabled(true);
  assertTrue(threadMXBean.isThreadCpuTimeEnabled());

  ThreadInfo[] threadInfo = threadMXBean.getThreadInfo(threadMXBean.getAllThreadIds());
  for (ThreadInfo threadInfo2 : threadInfo) {
   long blockedTime = threadInfo2.getBlockedTime();
   long waitedTime = threadInfo2.getWaitedTime();
   long cpuTime = threadMXBean.getThreadCpuTime(threadInfo2.getThreadId());
   long userTime = threadMXBean.getThreadUserTime(threadInfo2.getThreadId());

   String msg = String.format(
     "%s: %d ns cpu time, %d ns user time, blocked for %d ms, waited %d ms",
     threadInfo2.getThreadName(), cpuTime, userTime, blockedTime, waitedTime);
   System.out.println(msg);
  }
 }
}
mhaller