生成Java线程转储而不重新启动。
我想创建一个跟踪内存使用和CPU使用情况的线程。
如果应用程序达到高级别,我想生成堆转储或线程转储。
有没有办法生成线程转储运行时而不重新启动?
以下是我们以编程方式执行的操作: http : //pastebin.com/uS5jYpd4
我们使用JMX
ThreadMXBean
和ThreadInfo
类:
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 ,并将内容写入您想要的位置。