我如何在Java中获取当前的堆栈跟踪,就像在.NET中可以做Environment.StackTrace
什么一样?
我找到了,Thread.dumpStack()
但这不是我想要的-我想找回堆栈跟踪信息,而不是打印出来。
我如何在Java中获取当前的堆栈跟踪,就像在.NET中可以做Environment.StackTrace
什么一样?
我找到了,Thread.dumpStack()
但这不是我想要的-我想找回堆栈跟踪信息,而不是打印出来。
Answers:
您可以使用Thread.currentThread().getStackTrace()
。
这将返回一个StackTraceElement
s 数组,该数组代表程序的当前堆栈跟踪。
String fullStackTrace = org.apache.commons.lang.exception.ExceptionUtils.getFullStackTrace(e);
stackoverflow.com/a/10620951/11236
new Throwable().getStackTrace()
速度更快,因为它不需要检查this != Thread.currentThread()
并绕过通过子类(Exception extends Throwable
)调用它的潜在JVM开销
Thread.currentThread().getStackTrace();
如果您不在乎堆栈的第一个元素,那就很好了。
new Throwable().getStackTrace();
如果重要的话,将为您当前的方法定义位置。
(new Throwable()).getStackTrace()
是更快的执行过(见bugs.sun.com/bugdatabase/view_bug.do?bug_id=6375302)
(new Exception()).getStackTrace()
当请求的堆栈跟踪是当前线程(这将永远是对的情况下Thread.currentThread().getStackTrace();
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
new Exception().printStackTrace(System.out)
我记得,for循环的开销可能较小,但是无论如何您都应该将此作为调试工作……
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) { if(ste.toString().contains("mypackages")){ System.out.println(ste); } }
Thread.currentThread().getStackTrace();
从JDK1.5开始可用。
对于较旧的版本,您可以重定向exception.printStackTrace()
到StringWriter()
:
StringWriter sw = new StringWriter();
new Throwable("").printStackTrace(new PrintWriter(sw));
String stackTrace = sw.toString();
new Throwable().getStackTrace()
自JDK1.4起就可以使用…
您可以为此使用Apache的共同点:
String fullStackTrace = org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3
,完整的行是:org.apache.commons.lang3.exception.ExceptionUtils.getStackTrace(e);
org.apache.commons.lang3
,我最初忽略了它-导入使用lang3
代替lang
,并替换getFullStackTrace
为getStackTrace
。
ExceptionUtils.getStackTrace(new Throwable())
表达式来获取堆栈跟踪。
在android上,一种更简单的方法是使用此方法:
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
要获取所有线程的堆栈跟踪,可以使用jstack实用工具JConsole或发送kill -quit信号(在Posix操作系统上)。
但是,如果要以编程方式执行此操作,则可以尝试使用ThreadMXBean:
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()
;
System.err.println(elems[i])
在每个数组上执行)。摘要中的第二行bean.
之前没有,dumpAllThreads
但是我想大多数人都可以解决。
另一个解决方案(仅35个 31个字符):
new Exception().printStackTrace();
new Error().printStackTrace();
作为对已接受答案的评论,Tony给出了实际上是回答OP问题的最佳答案:
Arrays.toString(Thread.currentThread().getStackTrace()).replace( ',', '\n' );
...的OP也不要问如何获得String
从一个堆栈跟踪Exception
。而且,尽管我是Apache Commons的忠实拥护者,但是当事情像上面那样简单时,没有逻辑上的理由使用外部库。
Thread.getAllStackTraces()
,它会给您一个Map<Thread, StackTraceElement[]>
。热点将在需要安全指向一个线程时对所有线程进行安全指向。Zing可以将各个线程带到一个安全点,而不会干扰其他线程。获取stacktrace需要一个安全点。Thread.getAllStackTraces()
获取所有堆栈跟踪并仅停止所有线程一次。当然,你必须找出哪些映射你真正感兴趣的。
获取堆栈跟踪:
StackTraceElement[] ste = Thread.currentThread().getStackTrace();
打印堆栈跟踪(JAVA 8+):
Arrays.asList(ste).forEach(System.out::println);
打印堆叠(JAVA 7):
StringBuilder sb = new StringBuilder();
for (StackTraceElement st : ste) {
sb.append(st.toString() + System.lineSeparator());
}
System.out.println(sb);
在Java 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 );
}
我有一个实用程序方法,该方法返回带有堆栈跟踪的字符串:
static String getStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
t.printStackTrace(pw);
pw.flush();
sw.flush();
return sw.toString();
}
就像...登录
...
catch (FileNotFoundException e) {
logger.config(getStackTrace(e));
}
java.util.logging.Logger#log(Level, String, Throwable)
已经做到了。这是在不必要的情况下重写Java标准库中已经存在的内容,并为新开发人员指明了错误的方向,而该方向偏离了文档。现在,通过执行此操作,您已强制将Stacktrace格式化为某种格式,其中logging
API使您可以在指定时动态更改log语句的格式。据我所知,log4j
也有类似的行为。不要重新发明轮子,因为您最终会失去我所解释的东西。
Throwable
关闭的Handler
通过到S Formatter
S IN 2012这是Java7,比我在这里列出这些功能可以追溯到远长于Java7已经出现;因此J2SE 5.0的javadoc)
try {
}
catch(Exception e) {
StackTraceElement[] traceElements = e.getStackTrace();
//...
}
要么
Thread.currentThread().getStackTrace()
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
数组的最后一个元素表示堆栈的底部,这是序列中最近的方法调用。
A StackTraceElement has getClassName(), getFileName(), getLineNumber() and getMethodName().
遍历StackTraceElement并获得所需的结果。
for (StackTraceElement ste : stackTraceElements )
{
//do your stuff here...
}
我从上面使用了答案并添加了格式
public final class DebugUtil {
private static final String SEPARATOR = "\n";
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);
}
}
如果要检查进程的当前调用堆栈,可以使用jstack实用程序。
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
这是旧帖子,但这是我的解决方案:
Thread.currentThread().dumpStack();
此处提供了更多信息和更多方法:http : //javarevisited.blogspot.fr/2013/04/how-to-get-current-stack-trace-in-java-thread.html
Thread.dumpStack()
直接调用它,因为它是静态方法。