2014-02-27 82 views
2

我想知道什麼是java.lang.StackOverflowError的根本原因。 我知道它是在遞歸調用無限次的方法時發生的,但是異常的實際原因是什麼以及默認的堆棧大小是多少?java.lang.StackOverflowError的根本原因

+0

粘貼代碼.. – Kick

+0

默認大小由VM設置,但您可以使用-Xss JVM參數設置大小。 –

回答

0

只要內存的特定部分(「堆棧」)用完,就會發生stackoverflowerror。基本上你已經耗盡了分配給你的程序的內存,而不需要任何額外的內存,所以你的程序崩潰了。

具體來說,堆棧用於所有與調用函數和線程有關的東西,所以理論上你甚至可以通過創建一個新線程(儘管你首先需要幾乎用函數調用填充它)來耗盡內存。此外,遞歸不需要是無限的,只是非常大。

public int foo(int i){ 
    if (i=0) 
     return 0; 
    return (foo(i-1)+foo(i-1)%1000); 
} 

然後調用foo(10000)將導致沒有無限的計算器。

如果您對發現堆棧更感興趣,我會建議遞歸如何在更低級別的語言(如程序集)中工作,您可以真正看到機器正在做什麼(請注意,學習這將花費很多負擔得起,但會讓你成爲一個更好的程序員)。

1

只有在遞歸調用的情況下才會引發它。每當堆棧內存空間填充堆棧中的典型數據時就會拋出:局部變量,本地參數等等。

顯然,獲得堆棧溢出錯誤的機會隨着堆棧的大小(當前正在執行的方法和線程的根之間有多少方法調用)以及活動線程的數量而增加。

但是,正如我所提到的,遞歸調用並不是獲得大型堆棧的唯一原因。

0

如果選中doc

時發生堆棧溢出,因爲應用程序遞歸太深而引發。

now ..要知道爲什麼遞歸方法調用正在創建此錯誤,您應該知道java中調用方法的機制。

用簡單的句子來描述,當一個方法被調用時,方法調用的信息被壓入內存中的堆棧。當方法結束時意味着它被返回,然後信息被彈出。堆棧的大小不是無限的,所以當內存溢出並且你試圖調用另一個方法(即推送另一個方法調用的信息)時,它會拋出這個錯誤。

現在對於無限遞歸方法調用,你只是推入堆棧,但由於方法沒有完成,所以你不會彈出。所以肯定會出現上述情況..

我只是試圖用簡單的語言來描述。要知道更深入地檢查了許多有用的文章像following

1

的根本原因是這樣的:堆棧大小是固定的在運行時,與VM提供沒辦法,一旦程序運行進行調整。但遞歸深度不固定,在許多情況下它取決於輸入數據。這就是爲什麼遞歸深度有時候並不是所有的堆棧幀都適合堆棧的原因。

相關問題