程序中没有单一方法“知道”它在堆栈中的位置。所有它知道的是它自己的小工作,并且这样做并返回。所以当抛出异常并打印堆栈跟踪时,这是从哪里来的?堆栈跟踪如何生成?
是否隐式地在JVM中的每个应用程序旁边运行单独的线程来监视程序的状态?或者,JVM本身是否拥有这些信息,并且Exceptions在抛出时会以某种方式从中提取数据?
如果其中任何一种情况发生,是否可以使用某个调用来检索堆栈跟踪(无论是从监视器Thread还是JVM)而不是抛出异常?
程序中没有单一方法“知道”它在堆栈中的位置。所有它知道的是它自己的小工作,并且这样做并返回。所以当抛出异常并打印堆栈跟踪时,这是从哪里来的?堆栈跟踪如何生成?
是否隐式地在JVM中的每个应用程序旁边运行单独的线程来监视程序的状态?或者,JVM本身是否拥有这些信息,并且Exceptions在抛出时会以某种方式从中提取数据?
如果其中任何一种情况发生,是否可以使用某个调用来检索堆栈跟踪(无论是从监视器Thread还是JVM)而不是抛出异常?
每个线程都有自己的stack
。每个方法调用都会创建一个堆栈帧。如果在任何方法的代码中发生错误,将传播给调用方法。通过这种方式,JVM可以跟踪哪个方法产生错误,以及调用层次结构是什么。
如果您正确观察堆栈跟踪,您将看到错误发生在顶部和底部层次结构的方法。
斯坦福大学教授在youtube有一个伟大的演讲,了解它是如何工作的。我会建议看。
注意:这是理论。如果你想知道API的工作原理,@Peter Lawrey的答案可能会对你有所帮助。
它来自运行代码的Thread类。
Thread.dumpStack();
要看到它你可以:
StackTraceElement[] trace = Thread.currentThread().getStackTrace();
for (int i=0; i < trace.length; i++)
System.out.println("\tat " + trace[i]);
可以知道的方法,通过使用Thread.currentThread
属于线程。使用此线程,您可以获得StackTrace,因为JVM中的每个线程都有一个堆栈。另外,main
程序在main
线程中运行。
当你创建一个Throwable时(不是当你抛出它时)它会记录堆栈跟踪是与Throwable相关的低级别/隐藏方式。当您第一次调用getStackTrace()时,它将从低级信息创建StackTraceElement[]
对象。它不会这么懒惰,因为通常不会使用堆栈跟踪。
是的,我对这个理论很感兴趣。 :)这就是为什么我问这个问题,而不是为了任何特定的实际目的。 – asteri
好的,那么我的答案可能会提供一些线索,视频系列可能会填补空白。 – kosa