Which Java thread is hogging the CPU?
Try looking at the Hot Thread Detector plugin for visual VM -- it uses the ThreadMXBean API to take multiple CPU consumption samples to find the most active threads. It's based on a command-line equivalent from Bruce Chapman which might also be useful.
Obtaining CPU thread usage in Java
You can use ThreadMXBean
to get cpu usage statistics from all running threads. In the example below the CPU usage per thread
is calculated:
private int sampleTime = 10000;
private ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
private RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
private OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean();
private Map<Long, Long> threadInitialCPU = new HashMap<Long, Long>();
private Map<Long, Float> threadCPUUsage = new HashMap<Long, Float>();
private long initialUptime = runtimeMxBean.getUptime();
ThreadInfo[] threadInfos = threadMxBean.dumpAllThreads(false, false);
for (ThreadInfo info : threadInfos) {
threadInitialCPU.put(info.getThreadId(), threadMxBean.getThreadCpuTime(info.getThreadId()));
}
try {Thread.sleep(sampleTime);} catch (InterruptedException e) {}
long upTime = runtimeMxBean.getUptime();
Map<Long, Long> threadCurrentCPU = new HashMap<Long, Long>();
ThreadInfo[] threadInfos = threadMxBean.dumpAllThreads(false, false);
for (ThreadInfo info : threadInfos) {
threadCurrentCPU.put(info.getThreadId(), threadMxBean.getThreadCpuTime(info.getThreadId()));
}
// CPU over all processes
//int nrCPUs = osMxBean.getAvailableProcessors();
// total CPU: CPU % can be more than 100% (devided over multiple cpus)
long nrCPUs = 1;
// elapsedTime is in ms.
long elapsedTime = (upTime - initialUptime);
for (ThreadInfo info : threadInfos) {
// elapsedCpu is in ns
Long initialCPU = threadInitialCPU.get(info.getThreadId());
if (initialCPU != null) {
long elapsedCpu = threadCurrentCPU.get(info.getThreadId()) - initialCPU;
float cpuUsage = elapsedCpu / (elapsedTime * 1000000F * nrCPUs);
threadCPUUsage.put(info.getThreadId(), cpuUsage);
}
}
// threadCPUUsage contains cpu % per thread
System.out.println(threadCPUUsage);
// You can use osMxBean.getThreadInfo(theadId) to get information on every thread reported in threadCPUUsage and analyze the most CPU intentive threads
How to find a Java thread running on Linux with ps -axl?
Use
jps -v
for finding your java process. Sample Output:
3825 RemoteMavenServer -Djava.awt.headless=true -Xmx512m -Dfile.encoding=MacRoman
6172 AppMain -Didea.launcher.port=7533 -Didea.launcher.bin.path=/Applications/IntelliJ IDEA 10.app/bin -Dfile.encoding=UTF-8
6175 Jps -Dapplication.home=/Library/Java/JavaVirtualMachines/1.6.0_31-b04-411.jdk/Contents/Home -Xms8m
Then use
jstack 6172
(6172 is id of your process) to get stack of threads inside jvm. Thread priority could be found from it. Sample output:
.....
"main" **prio=5** tid=7ff255800800 nid=0x104bec000 waiting on condition [104beb000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at au.com.byr.Sample.main(Sample.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
.....
Enjoy!
EDIT: If application running under different user than yourself (typical case on production and other non-local environments) then jps/jstack should be run via sudo. Examples:
sudo jps -v
sudo jstack 6172
High CPU Utilization in java application - why?
If a profiler is not applicable in your setup, you may try to identify the thread following steps in this post.
Basically, there are three steps:
- run
top -H
and get PID of the thread with highest CPU. - convert the PID to hex.
- look for thread with the matching HEX PID in your thread dump.
Related Topics
Does Spring @Transactional Attribute Work on a Private Method
Using Xdg Directory Specification on Java Application
Cmake Can't Find Java, But It's Installed
How to Install Java Application to My Linux System
Exception While Submitting a Mapreduce Job from Remote System
Error While Loading Shared Libraries: Libjli.So in Java
Create Jfreechart-1.5.3 Jar from Source Code
Execute Source Command from Java
Synchronized Block on Grails Works on Windows But No in Linux
Practical Limitations of Jvm Memory and CPU Usage
Redirect Java -Version to File or Variable
In Java, "5/0" Statement Doesn't Fire Sigfpe Signal on My Linux MAChine, Why
Sending Command to Java -Jar Using Stdin via /Proc/{Pid}/Fd/0
Java Installation Issues on Ubuntu
Eclipse Swt Browser Crash (Linux 64Bit)
What Could Be Reason for "Prism-Es2 Error:Gl_Version (Major.Minor) = 1.4"