程序中沒有單一方法「知道」它在堆棧中的位置。所有它知道的是它自己的小工作,並且這樣做並返回。所以當拋出異常並打印堆棧跟蹤時,這是從哪裏來的?堆棧跟蹤如何生成?
是否隱式地在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