Skip to content

Instantly share code, notes, and snippets.

@logpresso
Created February 1, 2017 14:35
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save logpresso/c7928aefac3f094bef5905c5284eb9cb to your computer and use it in GitHub Desktop.
Save logpresso/c7928aefac3f094bef5905c5284eb9cb to your computer and use it in GitHub Desktop.
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.lang.management.LockInfo;
import java.lang.management.ManagementFactory;
import java.lang.management.MonitorInfo;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class JstackHelper {
private static final String LF;
static {
LF = System.getProperty("line.separator");
}
public static void dump(OutputStream os) throws IOException {
String jvmInfo = "Full thread dump " + property("java.vm.name") + "(" + property("java.runtime.version") + " "
+ property("java.vm.info") + ")" + LF;
String osInfo = property("os.name") + " (version=" + property("os.version") + ", arch=" + property("os.arch") + ")" + LF
+ LF;
Writer writer = new OutputStreamWriter(os, "utf-8");
writer.write(jvmInfo + LF);
writer.write("Operating System" + LF);
writer.write("------------------" + LF);
writer.write(osInfo);
writer.write("Environment Variables" + LF);
writer.write("-----------------------" + LF);
for (Object key : System.getProperties().keySet()) {
writer.write(key + "=" + System.getProperty(key.toString()) + LF);
}
writer.write(LF);
ThreadMXBean bean = ManagementFactory.getThreadMXBean();
long[] tids = bean.getAllThreadIds();
writer.write("Thread dump (total=" + tids.length + ")" + LF);
writer.write("------------------------------------------" + LF);
for (ThreadInfo t : bean.getThreadInfo(tids, true, true)) {
if (t == null)
continue;
writer.write("\"" + t.getThreadName() + "\" tid=" + t.getThreadId() + ": (state = " + t.getThreadState() + ")" + LF);
writer.write(mergeStackTrace(t));
writer.write(LF);
}
writer.flush();
}
private static String property(String name) {
String s = System.getProperty(name);
if (s == null)
return "";
return s;
}
private static String mergeStackTrace(ThreadInfo t) {
StackTraceElement[] stacktrace = t.getStackTrace();
MonitorInfo[] monitors = t.getLockedMonitors();
int idx = 0;
StringBuilder sb = new StringBuilder();
for (StackTraceElement el : stacktrace) {
LockInfo lock = t.getLockInfo();
String lockOwner = t.getLockOwnerName();
sb.append(String.format(" at %s.%s%s" + LF, el.getClassName(), el.getMethodName(), getFileAndLineNumber(el)));
if (idx == 0) {
if (el.getClassName().equals("java.lang.Object") && el.getMethodName().equals("wait")) {
if (lock != null) {
sb.append(String.format(" - waiting on <0x%016x> (%s)" + LF, lock.getIdentityHashCode(),
lock.getClassName()));
}
} else if (lock != null) {
if (lockOwner == null) {
sb.append(String.format(" - parking to wait for <0x%016x> (%s)" + LF, lock.getIdentityHashCode(),
lock.getClassName()));
} else {
sb.append(String.format(" - waiting to lock <0x%016x> (%s) owned by \"%s\" @%d" + LF,
lock.getIdentityHashCode(), lock.getClassName(), lockOwner, t.getLockOwnerId()));
}
}
}
for (MonitorInfo monitor : monitors) {
if (monitor.getLockedStackDepth() == idx) {
sb.append(String.format(" - locked <0x%016x> (%s)\n", monitor.getIdentityHashCode(), monitor.getClassName()));
}
}
idx++;
}
return sb.toString();
}
private static String getFileAndLineNumber(StackTraceElement el) {
if (el.getFileName() != null && el.getLineNumber() > 0)
return String.format(" (%s:%d)", el.getFileName(), el.getLineNumber());
else if (el.getFileName() != null && el.getLineNumber() <= 0)
return String.format(" (%s)", el.getFileName());
else
return "";
}
}
Full thread dump Java HotSpot(TM) 64-Bit Server VM(1.8.0_60-b27 mixed mode)
Operating System
------------------
Windows 10 (version=10.0, arch=amd64)
Environment Variables
-----------------------
(..omitted..)
Thread dump (total=5)
------------------------------------------
"Attach Listener" tid=5: (state = RUNNABLE)
"Signal Dispatcher" tid=4: (state = RUNNABLE)
"Finalizer" tid=3: (state = WAITING)
at java.lang.Object.wait (Object.java)
- waiting on <0x000000002a139a55> (java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:143)
at java.lang.ref.ReferenceQueue.remove (ReferenceQueue.java:164)
at java.lang.ref.Finalizer$FinalizerThread.run (Finalizer.java:209)
"Reference Handler" tid=2: (state = WAITING)
at java.lang.Object.wait (Object.java)
- waiting on <0x0000000015db9742> (java.lang.ref.Reference$Lock)
at java.lang.Object.wait (Object.java:502)
at java.lang.ref.Reference$ReferenceHandler.run (Reference.java:157)
"main" tid=1: (state = RUNNABLE)
at sun.management.ThreadImpl.dumpThreads0 (ThreadImpl.java)
at sun.management.ThreadImpl.getThreadInfo (ThreadImpl.java:440)
at JstackHelper.dump (JstackHelper.java:52)
at Sandbox.main (Sandbox.java:9)
@v0o0v
Copy link

v0o0v commented Feb 7, 2017

좋은 정보 감사합니다.
혹시 해당 코드의 라이센스가 어떻게 되는지 알 수 있나요?
회사에서 판매하는 제품에 해당 코드를 사용해도 되는지 알고 싶습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment