生成Java线程转储而不重新启动。

我想创建一个跟踪内存使用和CPU使用情况的线程。

如果应用程序达到高级别,我想生成堆转储或线程转储。

有没有办法生成线程转储运行时而不重新启动?

以下是我们以编程方式执行的操作: http : //pastebin.com/uS5jYpd4

我们使用JMX ThreadMXBeanThreadInfo类:

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

您还可以在~unix下执行kill -QUIT pid以将堆栈转储到标准输出。 还有jstack来转储JVM的堆栈。

如果应用程序的负载平均值高于某个阈值,我们还有一个自动转储堆栈:

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

要将线程转储到标准输出,您可以执行类似的操作

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

在Java 6中使用ThreadMXBean类。 但我建议使用真正的日志而不是标准输出。

尝试“kill -QUIT”Process_id例如

 kill -QUIT 2134 

这将触发线程转储而不重新启动它

是的,您可以使用内置管理MXBeans生成自己的堆栈转储。 具体来说,您可以从ThreadMXBean获取所有当前的ThreadInfos ,并将内容写入您想要的位置。