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?
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
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 (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.