Generate a Java thread dump without restarting.

巧了我就是萌 提交于 2019-11-28 01:04:18

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;
}

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

ThreadInfo[] threads = ManagementFactory.getThreadMXBean()
        .dumpAllThreads(true, true);
for(final 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.

Try “kill –QUIT” Process_id e.g

kill -QUIT 2134

This will trigger the thread dump without restarting it

Yes, you can generated your own stack dump using the built-in management MXBeans. Specifically, you can get all the current ThreadInfos From the ThreadMXBean and write the contents to your desired location.

In spring application, we can generate heap dump programmatically by creating cron job.

import com.sun.management.HotSpotDiagnosticMXBean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.management.MBeanServer;
import java.io.File;
import java.lang.management.ManagementFactory;

@Component
public class HeapDumpGenerator {
    @Scheduled(cron = "0 0/5 * * * *")
    public void execute() {
        generateHeapDump();
    }

    private void generateHeapDump() {
        MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer();
        String dumpFilePath = System.getProperty("user.home") + File.separator + 
                "heap-dumps" + File.separator +
                "dumpfile_" + System.currentTimeMillis() + ".hprof";
        try {
            HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean = ManagementFactory
                .newPlatformMXBeanProxy(mBeanServer,
                                    "com.sun.management:type=HotSpotDiagnostic", 
                                    HotSpotDiagnosticMXBean.class);
            hotSpotDiagnosticMXBean.dumpHeap(dumpFilePath, Boolean.TRUE);
        } catch (Exception e) {
            // log error
        }
    }
}

It will run at every five minutes, but we can set our own time/interval. We can also add condition before calling generateHeapDump() method.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!