2012-10-12 147 views
3

程序中没有单一方法“知道”它在堆栈中的位置。所有它知道的是它自己的小工作,并且这样做并返回。所以当抛出异常并打印堆栈跟踪时,这是从哪里来的?堆栈跟踪如何生成?

是否隐式地在JVM中的每个应用程序旁边运行单独的线程来监视程序的状态?或者,JVM本身是否拥有这些信息,并且Exceptions在抛出时会以某种方式从中提取数据?

如果其中任何一种情况发生,是否可以使用某个调用来检索堆栈跟踪(无论是从监视器Thread还是JVM)而不是抛出异常?

回答

5

每个线程都有自己的stack。每个方法调用都会创建一个堆栈帧。如果在任何方法的代码中发生错误,将传播给调用方法。通过这种方式,JVM可以跟踪哪个方法产生错误,以及调用层次结构是什么。

如果您正确观察堆栈跟踪,您将看到错误发生在顶部和底部层次结构的方法。

斯坦福大学教授在youtube有一个伟大的演讲,了解它是如何工作的。我会建议看。

注意:这是理论。如果你想知道API的工作原理,@Peter Lawrey的答案可能会对你有所帮助。

+0

是的,我对这个理论很感兴趣。 :)这就是为什么我问这个问题,而不是为了任何特定的实际目的。 – asteri

+0

好的,那么我的答案可能会提供一些线索,视频系列可能会填补空白。 – kosa

4

它来自运行代码的Thread类。

Thread.dumpStack(); 

要看到它你可以:

StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 
    for (int i=0; i < trace.length; i++) 
     System.out.println("\tat " + trace[i]); 
3

可以知道的方法,通过使用Thread.currentThread属于线程。使用此线程,您可以获得StackTrace,因为JVM中的每个线程都有一个堆栈。另外,main程序在main线程中运行。

3

当你创建一个Throwable时(不是当你抛出它时)它会记录堆栈跟踪是与Throwable相关的低级别/隐藏方式。当您第一次调用getStackTrace()时,它将从低级信息创建StackTraceElement[]对象。它不会这么懒惰,因为通常不会使用堆栈跟踪。