如何获取Java中的当前堆栈跟踪,比如如何在.NET中实现EDOCX1?0?
顺便说一句,Thread.dumpStack()不是我想要的——我想取回堆栈跟踪,而不是打印出来。
- 在Eclipse中调试时,我总是使用"new exception().printstacktrace()"作为监视表达式。当您在一个断点处挂起并想知道您来自哪里时,这很方便。
- @Tim&252;the:当您处于调试模式时,Eclipse是否已经告诉您堆栈跟踪?我认为是这样。
- array.toString(thread.currentThread().getStackTrace());足够简单。
- 问题文本询问.NET,但标签名为Java。这个问题是关于.NET还是Java(或者两者都适用)?
- "Arkanon"指的是Java,并展示了他们如何在.NET中实现它,Java中的等价物是什么。
- 要打印得很好,可以使用apache stringutils:stringutils.join(currenthread().getstacktrace(),"n")。
- LuigiMG-我们不能假设它们在Eclipse或任何其他开发环境中。如果他们是,并且可以停止程序,那么很好。但是相反,例如,将堆栈跟踪的一部分放在服务的日志文件中,以便以后进行问题诊断,这通常很有用。
您可以使用Thread.currentThread().getStackTrace()。
返回表示程序当前堆栈跟踪的StackTraceElement的数组。
- 如果您已经在使用ApacheCommons获取字符串,那么这是一个很酷的一行程序:String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);stackoverflow.com/a/10620951/11236
- 数组中的第一个元素(索引0)是java.lang.thread.getStackTrace方法,第二个(索引1)通常是第一个感兴趣的元素。
- 一个一行程序,用于将堆栈跟踪转换为一个字符串,该字符串在没有异常且不使用apache array.toString(thread.currentThread().getStackTrace()时工作。
- 很少看到500件战利品被认领
- @托尼的解决方案更好,因为它不需要一次性的
- 正如下面的许多答案所指出的,new Throwable().getStackTrace()更快,因为它不需要检查this != Thread.currentThread()并绕过通过子类调用它的潜在JVM开销(Exception extends Throwable)。
- 但在本例中,它将返回数组,我们如何才能在不遍历整个数组的情况下,具体地获取调用该方法的类名?
- 您是否将某个属性设置为vm以能够转储stacktrace?如果无法修改代码,则不添加代码
- @Ripper234谢谢你的评论,这很有用。我注意到在复制粘贴时,注释中有一些奇怪的布局字符会导致编译错误。你能编辑一下吗?它们是一个零宽度的非连接程序,在getfullstacktrace中的第一个c之后是一个零宽度空间。(可以在HTML源代码中看到)
1
| Thread. currentThread(). getStackTrace(); |
如果您不关心堆栈的第一个元素是什么,就可以了。
如果这很重要的话,将为您当前的方法定义一个位置。
- (new Throwable()).getStackTrace()的执行速度也更快(参见bugs.sun.com/bugdatabase/view_bug.do?错误ID=6375302)
- 您能更详细地解释thread.currentThread().getStackTrace()的结果如何不同于new throwable().getStackTrace()?我尝试了两种方法,发现thread.currentThread().getStackTrace()返回索引0中带有thread.getStackTrace的AM数组,调用方法位于索引1。新的throwable().getStackTrace()方法返回索引0处具有调用方法的数组。似乎两种方法都为当前方法定义了位置,但位置不同。你指出的还有别的区别吗?
- @Ryan,不能保证thread.currentThread().getStackTrace()不承诺在方法的不同版本上保持该位置。所以当你碰巧检查它时,它在索引1上。在Sun的一些版本的JVM(1.5或1.6,不记得了)上,它是索引2。这就是我所说的一个定义好的位置——规范要求它在那里,并在将来留在那里。
- "MyTye"bug现在被报告为Java 6中固定的关闭。从内部看,当请求的堆栈跟踪在当前线程上时(对于EDOCX1[9]通常是这样),它现在看起来像是执行EDOCX1[8]
- @强野:在你写评论之前,你所链接的bug已经被修复了六年。
- @Mjustin:这个bug并没有"现在"被报告为已修复,甚至在6年前就被修复了,直到Mightye写下评论。事实上,它甚至在stackoverflow建立之前就已经被修复了…
- 调试代码是一个很棒的技巧:D.工作得很好!
1 2 3
| for (StackTraceElement ste : Thread. currentThread(). getStackTrace()) {
System. out. println(ste );
} |
- 爪哇有一种印刷方法,你可以这样做:我记得的,环形可能性较小,但你只能用这作为解开任何事情的方法。
- 我喜欢这首最好的歌,因为你有机会通过写你的打印声明
1
| Thread. currentThread(). getStackTrace(); |
自JDK1.5起提供。
对于旧版本,您可以将exception.printStackTrace()重定向到StringWriter():
您可以使用Apache的公共资源:
1
| String fullStackTrace = org. apache. commons. lang3. exception. ExceptionUtils. getStackTrace(e ); |
- 这是一条很好的线路解决方案。所有线路都是:org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
- Just to reiterate fileofset's how when moving to org.apache.commons.lang3,which I'm initially overlooked--the import use lang3instead of lang,and replaces getFullStackTracewith edoc1〔15〕
- 这是非常有用的!当使用IDE(例如,Intellij idea)解码时,使用ExceptionUtils.getStackTrace(new Throwable())表示能得到堆栈的痕迹是很重要的。
在安卓系统上,更简单的方法是使用:
1 2
| import android.util.Log;
String stackTrace = Log. getStackTraceString(exception ); |
- Getstacktracisting defined在哪里?这是第三党派的测井图书馆吗?
- Android.util.log.getstacktracistring developer.android.com/reference/android/utile/log.html
另一个解决方案(仅限3531个字符):
- Awesome solution.现在我不需要穿过所有的堆栈架
要获取所有线程的堆栈跟踪,可以使用jstack实用程序jconsole或发送kill-quit信号(在POSIX操作系统上)。
但是,如果您想以编程方式执行此操作,可以尝试使用threadmxbean:
1 2 3 4 5 6 7
| ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);
for (ThreadInfo info : infos) {
StackTraceElement[] elems = info.getStackTrace();
// Print out elements, etc.
} |
如前所述,如果您只需要当前线程的堆栈跟踪,那么就容易多了——只需使用Thread.currentThread().getStackTrace();
- 此答案中的代码片段最接近以编程方式生成在发送JVM时看到的转储类型,即退出信号(在类似Unix的系统上)或在Windows上看到的转储类型。与其他答案不同的是,您可以看到监视器和同步器以及堆栈跟踪(例如,如果您迭代stacktraceelement数组并对每个数组执行System.err.println(elems[i]))。代码片段中的第二行在dumpAllThreads之前缺少bean.,但我想大多数人都能解决这个问题。
- 谢谢乔治-修改了我的代码示例。
傻我,我是Thread.currentThread().getStackTrace();。
作为对已接受答案的评论,托尼给出了似乎是最好的答案,实际上回答了OP的问题:
…操作员没有询问如何从Exception的堆栈跟踪中获取String。尽管我是ApacheCommons的忠实粉丝,但当有像上面这样简单的事情发生时,使用外部库是没有逻辑理由的。
- 我有一份威胁清单,我需要打印他们的堆栈痕迹。
- 在这种情况下,一定要使用Thread.getAllStackTraces(),它会给你一个Map。Hotspot将在需要安全点1时保护所有线程。zing可以将单个线程带到安全点,而不会干扰其他线程。获取stacktrace需要安全点。Thread.getAllStackTraces()获取所有堆栈跟踪并仅停止一次所有线程。当然,您必须找出您真正感兴趣的映射。
我建议
这是一种更简单的方法,它的优点是在可能根本没有问题的情况下,不会实际构造异常或可丢弃,而且更切题。
- 好的,实际上dumpStack()是一个静态方法,应该以静态方式访问。谢谢,Eclipse!
- 我喜欢这个快捷方式,但是这个方法的源代码是:new Exception("Stack trace").printStackTrace();,所以它实际上正在构建一个可丢弃的
在Java 9中有一种新的方法:
1 2 3 4 5 6 7 8 9
| public static void showTrace () {
List <StackFrame > frames =
StackWalker. getInstance( Option. RETAIN_CLASS_REFERENCE )
. walk( stream -> stream. collect( Collectors. toList() ) );
for ( StackFrame stackFrame : frames )
System. out. println( stackFrame );
} |
要用番石榴串起来:
1
| Throwables. getStackTraceAsString(new Throwable()) |
我有一个实用方法,它返回带有stacktrace的字符串:
只是逻辑上…
- 这看起来像一辆汽车由Netbeans生成。
- 是在一个房间里存储一个房间或一个你创建并写入文件的房间。
- @Doug Hauf,Logger is a reference to the built in Java Logger.请您设定标识属性文件。Addit it at the beginning of your class like this:private static final logger logger=logger.getlogger(your uu class.getname();
- 阿尔雷迪做了这个。这是重新写入在爪哇标准图书馆中已经存在的不需要的东西,并指向错误的方向的新的发展者,从文献中消失。API allows you to vary formating the log statement movically as you specified it.同样,我也有类似的行为。别再回来了因为你失去了我所解释的一切
- @Searchengine27 My How was from 2012,are we talking the same version of Java?拿个孩子的枕头你迟到了,我的朋友回答了。
- 它也存在于2012年。Date doesn't make a difference in your case,unfortunately.See [link](docs.oracle.com/javase/1.5.0/docs/api/java/util/loggi??ng/Logger.html#log(j??ava.util.logging.Lev??el, java.lang.String, java.lang.Throwable)), [link](docs.oracle.com/javase/1.5.0/docs/api/java/util/loggi??ng/Logger.html#log(j??ava.util.logging.Log??Record)), etc (there aRe several functions that pass the Throwableoff to the Handlers through the Formatters in 2012 which was Java7,more than I listed here.这些函数的长度远远超过Java7已被围绕;HENCE J2SE 5.0 Javadocs)
1 2 3 4 5 6
| try {
}
catch(Exception e ) {
StackTraceElement [] traceElements = e. getStackTrace();
//...
} |
或
1
| Thread. currentThread(). getStackTrace() |
- 您的最上面的示例是否只提供与try/catch块相关的堆栈跟踪?
- 会的。
- 这两者有什么区别
正在获取StackTrace:
1
| StackTraceElement [] ste = Thread. currentThread(). getStackTrace(); |
打印堆栈跟踪(Java 8 +):
打印堆栈(Java 7):
1 2 3 4 5 6
| StringBuilder sb = new StringBuilder ();
for (StackTraceElement st : ste ) {
sb. append(st. toString() + System. lineSeparator());
}
System. out. println(sb ); |
1
| StackTraceElement [] stackTraceElements = Thread. currentThread(). getStackTrace(); |
The last element of the array represents the bottom of the stack, which is the least recent method invocation in the sequence.
1
| A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName(). |
通过stacktraceelement循环并获得所需的结果。
1 2 3 4
| for (StackTraceElement ste : stackTraceElements )
{
//do your stuff here...
} |
- 谢谢你说出最近最新的元素。反直觉,挽救我一段时间。
- 还将输出所有数据优化为条纹。
也许你可以试试这个:
字符串"errordetail"包含stacktrace。
如果要检查进程的当前调用堆栈,可以使用jstack实用程序。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F [-m] [-l] <pid>
(to connect to a hung process)
jstack [-m] [-l] <executable> <core>
(to connect to a core file)
jstack [-m] [-l] [server_id@]<remote server IP or hostname>
(to connect to a remote debug server)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message |
我使用了上面的答案并添加了格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| public final class DebugUtil {
private static final String SEPARATOR ="
";
private DebugUtil () {
}
public static String formatStackTrace (StackTraceElement [] stackTrace ) {
StringBuilder buffer = new StringBuilder ();
for (StackTraceElement element : stackTrace ) {
buffer. append(element ). append(SEPARATOR );
}
return buffer. toString();
}
public static String formatCurrentStacktrace () {
StackTraceElement [] stackTrace = Thread. currentThread(). getStackTrace();
return formatStackTrace (stackTrace );
}
} |
这是一篇旧文章,但我的解决方案是:
1
| Thread. currentThread(). dumpStack(); |
更多信息和方法:http://javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html
- 自从螺纹.dumpstack()是静态的,你应该直接叫它。
- The op indicated that they want a reference in code to the stack trace,not to print it out.
- 你应该直接打电话给Thread.dumpStack(),因为它的静态方法。
System.out.println(Arrays.toString(Thread.currentThread().getStackTrace()));
这将帮助您无需循环打印堆栈跟踪。