package org.gridkit.jvmtool; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.util.concurrent.TimeUnit; import javax.management.MBeanServerConnection; import org.gridkit.jvmtool.codec.stacktrace.ThreadSnapshotEvent; import org.gridkit.jvmtool.codec.stacktrace.ThreadSnapshotEventPojo; import org.gridkit.jvmtool.codec.stacktrace.ThreadSnapshotWriter; import org.gridkit.jvmtool.event.Event; import org.gridkit.jvmtool.event.EventReader; import org.gridkit.jvmtool.event.TypedEventWriterProxy; import org.gridkit.jvmtool.event.UniversalEventWriter; import org.gridkit.jvmtool.gcmon.GarbageCollectionEvent; import org.gridkit.jvmtool.gcmon.GarbageCollectionEventWriter; import org.gridkit.jvmtool.gcmon.GcEventSubscriber; import org.gridkit.jvmtool.gcmon.SimpleGcEventEncoder; import org.gridkit.jvmtool.stacktrace.StackTraceWriter; import org.gridkit.jvmtool.stacktrace.ThreadDumpSampler; import org.gridkit.jvmtool.stacktrace.ThreadEventCodec; import org.gridkit.jvmtool.stacktrace.ThreadMXBeanEx; import org.gridkit.jvmtool.stacktrace.ThreadSnapshot; import org.gridkit.lab.jvm.attach.AttachManager; import org.junit.Test; public class CaptureCheck { private static long PID; static { String pid = ManagementFactory.getRuntimeMXBean().getName(); pid = pid.substring(0, pid.indexOf('@')); PID = Long.valueOf(pid); // PID = xxx; } private String taget = "target/test.cap"; private long captureTime = TimeUnit.SECONDS.toMillis(30); @Test public void capture() throws FileNotFoundException, IOException { File dump = new File(taget); if (dump.getParentFile() != null) { dump.getParentFile().mkdirs(); } UniversalEventWriter writer = ThreadEventCodec.createEventWriter(new FileOutputStream(dump)); MyEventWriter twriter = TypedEventWriterProxy.decorate(writer) .pass(ThreadSnapshotEvent.class) .pass(GarbageCollectionEvent.class) .facade(MyEventWriter.class); MBeanServerConnection conn = AttachManager.getJmxConnection(PID); GcEventSubscriber subscriber = new GcEventSubscriber(conn, new SimpleGcEventEncoder(twriter)); if (!subscriber.subscribe()) { // polling fallback subscriber.schedule(500); } ThreadDumpSampler tdumper = new ThreadDumpSampler(); ThreadMXBean threadMXBean = ThreadMXBeanEx.BeanHelper.connectThreadMXBean(conn); if (threadMXBean.isThreadContentionMonitoringSupported()) { threadMXBean.setThreadContentionMonitoringEnabled(true); } tdumper.connect(threadMXBean); long deadline = System.currentTimeMillis() + captureTime; ThreadEventAdapter threadWriter = new ThreadEventAdapter(twriter); while(System.currentTimeMillis() < deadline) { tdumper.collect(threadWriter); } twriter.close(); System.out.println("Dump complete [" + dump.getPath() + "] " + dump.length() + " bytes"); int tc = 0; int ntc = 0; EventReader<Event> reader = ThreadEventCodec.createEventReader(new FileInputStream(dump)); for(Event e: reader) { if (e instanceof ThreadSnapshotEvent) { ++tc; } else { ++ntc; } } System.out.println("Thread events: " + tc + " Non thread events: " + ntc); } private static class ThreadEventAdapter implements StackTraceWriter { final ThreadSnapshotWriter writer; public ThreadEventAdapter(ThreadSnapshotWriter writer) { this.writer = writer; } @Override public void write(ThreadSnapshot snap) throws IOException { ThreadSnapshotEventPojo pojo = new ThreadSnapshotEventPojo(); pojo.loadFrom(snap); writer.storeThreadEvent(pojo); } @Override public void close() { writer.close(); } } public static interface MyEventWriter extends GarbageCollectionEventWriter, ThreadSnapshotWriter { } }