簡體   English   中英

java如何處理StackOverflowError?

[英]How java handles StackOverflowError?

這是我的示例應用程序

public class Main {

    private long[] exceptionLevels = new long[1000];
    private int index;

    public static void main(String... args) {
        Main main = new Main();
        try {
            main.foo(0);
        } finally {
            Arrays.stream(main.exceptionLevels)
                    .filter(x -> x != 0)
                    .forEach(System.out::println);
        }
    }

    private void foo(int level) {
        try {
            foo(level + 1);
        } catch (StackOverflowError e) {
            exceptionLevels[index++] = level;
            bar(level + 1);
        }
    }

    private void bar(int level) {
        try {
            bar(level + 1);
        } catch (StackOverflowError e) {
            exceptionLevels[index++] = -level;
        }
    }
}

有時,當我運行應用程序時,我會看到這樣的結果

8074
8073
-8074

這實際上意味着發生了以下情況

  • foo(8073)調用foo(8074)
  • foo(8074)調用foo(8075)而死
  • foo(8074)記錄自己並調用bar(8075)而死
  • foo(8074)死了,foo(8073)捕獲它,記錄自己並調用bar(8074)
  • bar(8074)調用bar(8075)死亡,因此bar(8074)自行記錄
  • 從所有方法返回,優雅地關閉

我明白了,一切都很好。 所以有一種可以理解的獲取模式

X, X-1, -X

對於呼叫X某些最高級別

但有時,調用Main會產生這種輸出

6962
6961
-6963

這實際上是

X, X-1, -(X+1)

所以問題是,怎么樣?

PS此外,當我將所有內容更改為靜態時,程序完全改變了它的行為,因此有時甚至會得到超過3個結果。

編輯:當我用-Xss228k運行時,我總是得到

1281
1280
-1281

但是再次使用-Xss1m運行-Xss1m-Xss1m隨機堆棧大小,有時會出現上述情況。

運行代碼可能會導致其他可能的輸出。 在我的電腦上(Java 8,Windows)我主要得到一對像:

7053
-7055

但在極少數情況下,我得到:

9667
9666
-9667

建議不要捕獲任何java.lang.Error ,這是JVM可能無法恢復的異常情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM