Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate a Java thread dump without restarting.

I'd like to create a thread that keeps track of the memory usage and cpu usage.

If the application reaches a high level, I want to generate an heap dump or a thread dump.

Is there a way to generate a Thread dump runtime without restarting?

like image 921
Matteo Gatto Avatar asked Oct 11 '12 14:10

Matteo Gatto


People also ask

How do you trigger a thread dump in Java?

Ctrl + Break (Windows) In Windows operating systems, we can capture a thread dump using the CTRL and Break key combination. To take a thread dump, navigate to the console used to launch the Java application, and press the CTRL and Break keys together.

Does thread dump stop JVM?

Yes, thread dump and heap dump are stop-the-world operations in JDK 8. HotSpot JVM performs them at the global safepoint. See this and this answers for more information. Save this answer.

How do I get thread and heap dump?

Heap dump = memory contents for the JVM process output to a binary file. To take a thread dump on Windows, CTRL + BREAK if your JVM is the foreground process is the simplest way. If you have a unix-like shell on Windows like Cygwin or MobaXterm, you can use kill -3 {pid} like you can in Unix.

What is difference between heap dump and thread dump?

A thread dump is a dump of the stacks of all live threads. Thus useful for analysing what an app is up to at some point in time, and if done at intervals handy in diagnosing some kinds of 'execution' problems (e.g. thread deadlock). A heap dump is a dump of the state of the Java heap memory.


2 Answers

Here's how we do it programmatically: http://pastebin.com/uS5jYpd4

We use the JMX ThreadMXBean and ThreadInfo classes:

ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = mxBean.getThreadInfo(mxBean.getAllThreadIds(), 0);
...

You can also do a kill -QUIT pid under ~unix to dump the stacks to the standard-out. There is also jstack to dump the stack of a JVM.

We also have an automation which dumps the stack if the load average of the application is above some threshold:

private long lastCpuTimeMillis;
private long lastPollTimeMillis;

public void checkLoadAverage() {
    long now = System.currentTimeMillis();
    long currentCpuMillis = getTotalCpuTimeMillis();
    double loadAvg = calcLoadAveragePercentage(now, currentCpuMillis);
    if (loadAvg > LOAD_AVERAGE_DUMP_THRESHOLD) {
        try {
            dumpStack("Load average percentage is " + loadAvg);
        } catch (IOException e) {
            // Oh well, we tried
        }
    }
    lastCpuTimeMillis = currentCpuMillis;
    lastPollTimeMillis = now;
}

private long getTotalCpuTimeMillis() {
    long total = 0;
    for (long id : threadMxBean.getAllThreadIds()) {
        long cpuTime = threadMxBean.getThreadCpuTime(id);
        if (cpuTime > 0) {
            total += cpuTime;
        }
    }
    // since is in nano-seconds
    long currentCpuMillis = total / 1000000;
    return currentCpuMillis;
}

private double calcLoadAveragePercentage(long now, long currentCpuMillis) {
    long timeDiff = now - lastPollTimeMillis;
    if (timeDiff == 0) {
        timeDiff = 1;
    }
    long cpuDiff = currentCpuMillis - lastCpuTimeMillis;
    double loadAvg = (double) cpuDiff / (double) timeDiff;
    return loadAvg;
}
like image 113
Gray Avatar answered Oct 23 '22 13:10

Gray


To dump the threads to the standard out, you may do something like this

ThreadInfo[] threads = ManagementFactory.getThreadMXBean()
        .dumpAllThreads(true, true);
for (ThreadInfo info : threads) {
    System.out.print(info);
}

in Java 6 using the ThreadMXBean class. But I would suggest to use real logging instead of the standard output.

like image 10
rolve Avatar answered Oct 23 '22 13:10

rolve