Generate a Java thread dump without restarting.

后端 未结 5 1389
别跟我提以往
别跟我提以往 2020-12-06 18:13

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

相关标签:
5条回答
  • 2020-12-06 18:20

    Try “kill –QUIT” Process_id e.g

    kill -QUIT 2134
    

    This will trigger the thread dump without restarting it

    0 讨论(0)
  • 2020-12-06 18:26

    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;
    }
    
    0 讨论(0)
  • 2020-12-06 18:28

    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.

    0 讨论(0)
  • 2020-12-06 18:30

    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.

    0 讨论(0)
  • 2020-12-06 18:31

    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.

    0 讨论(0)
提交回复
热议问题