2012-10-12 146 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[]對象。它不會這麼懶惰,因爲通常不會使用堆棧跟蹤。