Skip to content

Instantly share code, notes, and snippets.

@hikoma
Created May 20, 2012 14:42
Show Gist options
  • Save hikoma/2758340 to your computer and use it in GitHub Desktop.
Save hikoma/2758340 to your computer and use it in GitHub Desktop.
Prints java stack traces of java threads eating the CPU
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;
public class CpuMonitor {
private final ThreadMXBean threadMXBean;
private int threshold = 95;
private int maxDepth = Integer.MAX_VALUE;
private long period = 0;
private long prevSystemTime = 0;
private Map<Long, Long> prevCpuTimes = Collections.emptyMap();
public CpuMonitor() {
threadMXBean = ManagementFactory.getThreadMXBean();
}
public CpuMonitor(String serviceUrl) throws IOException {
if (serviceUrl == null) {
threadMXBean = ManagementFactory.getThreadMXBean();
} else {
JMXConnector connector = JMXConnectorFactory.connect(new JMXServiceURL(serviceUrl));
threadMXBean = ManagementFactory.newPlatformMXBeanProxy(connector.getMBeanServerConnection(),
ManagementFactory.THREAD_MXBEAN_NAME, ThreadMXBean.class);
}
}
public final void setThreshold(int threshold) {
this.threshold = threshold;
}
public final void setMaxDepth(int maxDepth) {
this.maxDepth = maxDepth;
}
public final void process() {
init();
Map<Long, Long> currentCpuTimes = new HashMap<Long, Long>();
long currentSystemTime = System.nanoTime();
long diff = (currentSystemTime - prevSystemTime) / 100;
for (long id : threadMXBean.getAllThreadIds()) {
long cpuTime = threadMXBean.getThreadCpuTime(id);
if (prevCpuTimes.containsKey(id)) {
long cpuUsage = (cpuTime - prevCpuTimes.get(id)) / diff;
if (cpuUsage >= threshold) {
handle(period, cpuUsage, threadMXBean.getThreadInfo(id, maxDepth));
}
}
currentCpuTimes.put(id, cpuTime);
}
period++;
prevSystemTime = currentSystemTime;
prevCpuTimes = currentCpuTimes;
}
protected void init() {
}
protected void handle(long period, long cpuUsage, ThreadInfo threadInfo) {
System.out.println("[" + cpuUsage + "%] " + threadInfo);
}
public static void main(String[] args) throws InterruptedException, IOException {
CpuMonitor monitor = new CpuMonitor(System.getProperty("serviceUrl"));
if (args.length >= 1) {
monitor.setThreshold(Integer.valueOf(args[0]));
}
while (true) {
monitor.process();
Thread.sleep(10000); // 10 seconds
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment