Java 中的 StackOverflowError 及示例
當棧空間耗盡時,就會發生 StackOverflowError。這是一個執行時錯誤,表示 JVM 已耗盡資源。此類錯誤的主要原因可能是:迴圈引用、無限遞迴或使用大量記憶體的繁重應用程式。
在本文中,我們將以儘可能簡單的方式討論上面列出的 StackOverflowError 的原因。
Java 中的 StackOverflowError
Java 中的記憶體管理
在深入瞭解 StackOverflowError 之前,瞭解 Java 如何為特定程式或應用程式管理記憶體空間非常重要。
執行程式的每個介面、類、物件、變數和方法都儲存在計算機記憶體的不同區域。引用變數、方法和類的名稱儲存在棧中,它們的值儲存在堆中。
每當一個程序啟動時,它都會自動定義一個固定的棧大小。在每次方法呼叫期間,會在呼叫棧上建立一個呼叫幀,並持續到方法呼叫結束。當棧空間中沒有剩餘空間來建立新的棧幀時,就會遇到 StackOverflowError。
語法
import java.lang.StackOverflowError;
此類位於 'java.lang' 包中。我們不需要顯式匯入此包。通常,此包中的類無需匯入即可自動在我們的程式中使用。但是,也有一些例外情況。
示例 1
以下示例說明了 StackOverflowError。
import java.lang.StackOverflowError; public class Overflw { public static void methodA(int n1) { n1++; methodB(n1); } public static void methodB(int n1) { n1++; methodA(n1); } public static void main(String []args) { int n1 = 0; methodA(n1); } }
輸出
Exception in thread "main" java.lang.StackOverflowError at Overflw.methodB(Overflw.java:9) at Overflw.methodA(Overflw.java:5) at Overflw.methodB(Overflw.java:9) at Overflw.methodA(Overflw.java:5) at Overflw.methodB(Overflw.java:9) at Overflw.methodA(Overflw.java:5) at Overflw.methodB(Overflw.java:9) at Overflw.methodA(Overflw.java:5) at Overflw.methodB(Overflw.java:9) at Overflw.methodA(Overflw.java:5) at Overflw.methodB(Overflw.java:9) at Overflw.methodA(Overflw.java:5) at Overflw.methodB(Overflw.java:9) at Overflw.methodA(Overflw.java:5) at Overflw.methodB(Overflw.java:9) at Overflw.methodA(Overflw.java:5) at Overflw.methodB(Overflw.java:9)
如您所見,示例 1 程式碼的輸出導致了 StackOverflowError。我們在上述程式碼中所做的是建立了兩個名為 'methodA' 和 'methodB' 的帶引數的使用者定義方法。在主方法中,我們宣告並初始化了一個整數變數 'n1' 為 0,並帶引數 'n1' 呼叫了 'methodA'。現在,'methodA' 帶 'n1' 的增量值呼叫了 'methodB'。然後,'methodB' 又呼叫了 'methodA',並且此過程重複多次。因此,在某些時候,為該程式建立的棧大小耗盡,導致以下錯誤。
我們可以採取以下措施來處理 StackOverflowError:
仔細檢查那些重複出現的行,並嘗試找出它們未終止的原因。
預設棧大小可能為 512KB 或 1MB,具體取決於已安裝的 Java 虛擬機器,但我們可以手動增加棧的大小以避免此錯誤。但是,此技術很少使用。
示例 2
現在,藉助此示例,我們將嘗試找到之前示例中出現的 StackOverflowError 的解決方案。
public class Overflw { public static void methodA(int n1) { n1++; methodB(n1); } public static void methodB(int n1) { n1++; int n2 = 5; int mult = n1 * n2; System.out.println("Value of n1 and n2 multiplication is: " + mult); } public static void main(String []args) { int n1 = 0; methodA(n1); } }
輸出
Value of n1 and n2 multiplication is: 10
在示例 1 中,程式的問題在於第 6 行和第 10 行沒有終止。但在上述示例中,我們添加了一個語句來終止程式並列印儲存在 'mult' 中的值。
結論
StackOverflowError 發生在執行時,而不是在編譯期間,因此正確處理它非常重要,否則可能會給我們帶來麻煩。解決此問題的最有效方法是仔細檢查發生錯誤的行。