有没有办法转储堆栈跟踪,而不会在java中引发exception?

我正在考虑为我的Java应用程序创build一个debugging工具。

我想知道是否有可能得到一个堆栈跟踪,就像Exception.printStackTrace()但实际上没有引发exception?

我的目标是,在任何给定的方法中,转储堆栈以查看调用方的方法。

您也可以尝试使用Thread.getAllStackTraces()获取所有活动线程的堆栈跟踪图。

是的,只需使用

 Thread.dumpStack() 

如果你想要跟踪当前线程(而不是系统中的所有线程,就像Ram的build议那样),请执行以下操作:

Thread.currentThread()。 的getStackTrace()

要查找来电者,请执行以下操作:

 private String getCallingMethodName() { StackTraceElement callingFrame = Thread.currentThread().getStackTrace()[4]; return callingFrame.getMethodName(); } 

并且从需要知道其调用者是谁的方法中调用该方法。 但是,警告一句话:列表中调用框架的索引可能会根据JVM而有所不同! 这一切都取决于getStackTrace中有多less层的调用,然后才能生成跟踪点。 更强大的解决scheme是获取跟踪,并遍历它寻找getCallingMethodName的框架,然后进一步find真正的调用者两个步骤。

你可以得到这样的堆栈跟踪:

 Throwable t = new Throwable(); t.printStackTrace(); 

如果你想访问框架,你可以使用t.getStackTrace()来获得一个堆栈帧数组。

请注意,如果热点编译器一直忙于优化事情,则此堆栈跟其他任何可能会丢失一些帧。

注意Thread.dumpStack()实际上引发了一个exception:

 new Exception("Stack trace").printStackTrace(); 

您也可以向JVM发送一个信号,通过向进程发送QUIT信号来执行正在运行的Java进程的Thread.getAllStackTraces()。

在Unix / Linux上使用:

kill -QUIT process_id ,其中process_id是Java程序的进程号。

在Windows上,您可以在应用程序中按下Ctrl-Break,但除非您正在运行控制台进程,否则您通常不会看到这一点。

JDK6引入了另一个选项,即jstack命令,它将显示计算机上正在运行的任何JDK6进程的堆栈:

jstack [-l] <pid>

这些选项对于在生产环境中运行且不能轻易修改的应用程序非常有用。 它们对诊断运行时死锁或性能问题特别有用。

http://java.sun.com/developer/technicalArticles/Programming/Stacktrace/ http://java.sun.com/javase/6/docs/technotes/tools/share/jstack.html

如果你需要捕获输出

 StringWriter sw = new StringWriter(); new Throwable("").printStackTrace(new PrintWriter(sw)); String stackTrace = sw.toString(); 

HPROF Java Profiler

你甚至不需要在代码中这样做。 您可以将Java HPROF附加到您的进程,并在任何时候点击Control- \输出堆转储,运行线程等。 。 。 而不会浪费您的应用程序代码。 这有些过时,Java 6自带GUI jconsole,但是我仍然发现HPROF非常有用。