`Monitor cpu usage per thread in java?

38,231

Solution 1

I believe the JConsole (archived link) does provide this kind of information through a plugin

JConsole Thread CPU usage, after blogs.oracle.com/lmalventosa/resource/thread_cpu_usage.jpg

It uses ThreadMXBean getThreadCpuTime() function.

Something along the line of:

        long upTime = runtimeProxy.getUptime();
        List<Long> threadCpuTime = new ArrayList<Long>();
        for (int i = 0; i < threadIds.size(); i++) {
            long threadId = threadIds.get(i);
            if (threadId != -1) {
                threadCpuTime.add(threadProxy.getThreadCpuTime(threadId));
            } else {
                threadCpuTime.add(0L);
            }
        }
        int nCPUs = osProxy.getAvailableProcessors();
        List<Float> cpuUsageList = new ArrayList<Float>();
        if (prevUpTime > 0L && upTime > prevUpTime) {
            // elapsedTime is in ms
            long elapsedTime = upTime - prevUpTime;
            for (int i = 0; i < threadIds.size(); i++) {
                // elapsedCpu is in ns
                long elapsedCpu = threadCpuTime.get(i) - prevThreadCpuTime.get(i);
                // cpuUsage could go higher than 100% because elapsedTime
                // and elapsedCpu are not fetched simultaneously. Limit to
                // 99% to avoid Chart showing a scale from 0% to 200%.
                float cpuUsage = Math.min(99F, elapsedCpu / (elapsedTime * 1000000F * nCPUs));
                cpuUsageList.add(cpuUsage);
            }
        }

Solution 2

by using java.lang.management.ThreadMXBean. How to obtain a ThreadMXBean:

 ThreadMXBean tmxb = ManagementFactory.getThreadMXBean();

then you can query how much a specific thread is consuming by using:

 long cpuTime = tmxb.getThreadCpuTime(aThreadID);

Hope it helps.

Solution 3

Option_1: Code level

In your business logic code; in the beginning call start() API and in the finally block call stop(). So that you will get CPU time for executing your logic by the current running thread. Then log it. Reference.

class CPUTimer 
{
    private long _startTime = 0l;

    public void start ()
    {
        _startTime = getCpuTimeInMillis();
    }


    public long stop ()
    {
        long result = (getCpuTimeInMillis() - _startTime);
        _startTime = 0l;
        return result;
    }

    public boolean isRunning ()
    {
        return _startTime != 0l;
    }

    /** thread CPU time in milliseconds. */
    private long getCpuTimeInMillis ()
    {
        ThreadMXBean bean = ManagementFactory.getThreadMXBean();
        return bean.isCurrentThreadCpuTimeSupported() ? bean.getCurrentThreadCpuTime()/1000000: 0L;
    }
}

Option_2: Monitor level using plugins (AIX IBM box which don't have jvisualvm support)

If you think it is delay in adding code now, then you can prefer JConsole with plugins support. I followed this article. Download the topthreads jar from that article and run ./jconsole -pluginpath topthreads-1.1.jar

Option_3: Monitor level using TOP (shift H) + JSTACK (Unix machine which has 'Shif+H' support)

Follow this tutorial, where top command will give option to find top CPU thread (nid). Take that check that nid in jstack output file.

Solution 4

Try the "TopThreads" JConsole plugin. See http://lsd.luminis.nl/top-threads-plugin-for-jconsole/

Solution 5

Though this is platform dependent, I believe what you're looking for is the ThreadMXBean: http://java.sun.com/j2se/1.5.0/docs/api/java/lang/management/ThreadMXBean.html . You can use the getThreadUserTime method, for example, to get what you need. To check if your platform supports CPU measurement, you can call isThreadCpuTimeSupported() .

Share:
38,231
awk
Author by

awk

Updated on January 04, 2020

Comments

  • awk
    awk over 4 years

    I would like to ask whether there is some simple way to determine cpu usage per thread in java. Thanks

  • Graham
    Graham almost 12 years
    Just a note, you might also want to check that CpuTime is enabled in the JVM which you are running. 'threadBean_.isThreadCpuTimeEnabled()' will return boolean value and you can always set it if it is not with 'threadBean_.setThreadCpuTimeEnabled(true)'
  • Joost
    Joost almost 7 years
  • Michael Sims
    Michael Sims about 3 years
    getThreadCPUTime is NOT the same as CPU % consumption - CPUTime tells you how much time the thread has used the CPU, not how much of the CPUs resources are being consumed in that moment.