问题描述
我想创建一个跟踪内存使用情况和cpu使用情况的线程。
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?
推荐答案
以下是我们如何以编程方式执行此操作:
Here's how we do it programmatically: http://pastebin.com/uS5jYpd4
我们使用 JMX
和 ThreadInfo
类:
ThreadMXBean mxBean = ManagementFactory.getThreadMXBean();
ThreadInfo[] threadInfos = mxBean.getThreadInfo(mxBean.getAllThreadIds(), 0);
...
您还可以执行 kill -QUIT pid
在~unix下将堆栈转储到标准输出。还有jstack来转储JVM的堆栈。
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;
}
这篇关于生成Java线程转储而不重新启动。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!