2011-01-19 20 views
78

StackOverflowErrorを取得する前に、コールスタックにどれだけ深く入る必要がありますか?答えはプラットフォームに依存していますか?Javaコールスタックの最大深度はどれくらいですか?

+1

密接に関連しています:http://stackoverflow.com/questions/794227/how-to-know-about-outofmemory-or-stackoverflow-errors-ahead-of-time – finnw

+0

これは良い質問ですから、タイトルを、意味とより明確に関連していると感じるものに更新しました。 (以前は、実行時にキャプチャした*特定のスタックの深さを指していると思っていました)。あなたが同意しないならば、それを元に戻してください。 –

+0

@Andrzej - 異議はありません。 – ripper234

答えて

48

スタックに割り当てられている仮想メモリの量によって異なります。

http://www.odi.ch/weblog/posting.php?posting=411

あなたは-Xss VMパラメータを使用してまたはThread(ThreadGroup, Runnable, String, long)コンストラクタに合わせ、これをすることができます。

+12

そしておそらくあなたが置いているスタックフレームのサイズですか? – duffymo

+1

制限は、関数のスタック使用量によっても異なります。 –

+0

もしXssについて言及しなければ、それは? –

19

スタックサイズは-Xssコマンドラインスイッチで設定できますが、経験則としては十分深く、何千もの呼び出しではないにしても数百もの深い呼び出しです。 (デフォルトはプラットフォームに依存しますが、ほとんどのプラットフォームで少なくとも256kです)。

スタックオーバーフローが発生した場合、コードのエラーの99%が原因です。

+3

+1は2番目の段落です。 1つは常にそれについて覚えておく必要があります。 – mcveat

+6

eclipseを使用すると、私は1024回の再帰呼び出ししか得られません。 – Norswap

+0

@Norswapあなたはスタックトレースのサイズによってそれを決定していますか?これはスタックの実際のサイズに関係なく1024に制限されているようです。 –

21

システムでテストした結果、一定の値が見つからない場合は、8900コール後にスタックオーバーフローが発生することがあります。

public class MainClass { 

    private static long depth=0L; 

    public static void main(String[] args){ 
     deep(); 
    } 

    private static void deep(){ 
     System.err.println(++depth); 
     deep(); 
    } 

} 
+7

これは尾を再帰的にしているのではなく、あふれてはいけませんか?編集:申し訳ありません。 Javaでは8027でクラッシュしました。私が退屈になる前にScalaでは8594755に達しました。 – arya

+6

@arya JVMセマンティクスの重要な部分は、末尾再帰がサポートされていないことです。これは、JVM上で末尾再帰を使用して言語を実装したい人にとって、興味深い問題がたくさんあります。 –

+1

'public foo(){try {foo(); }最後に{foo(); }} ' は、仮想的には永遠に、Javaでは実行できます。 – Felype

2

は、これら二つのコールの比較:
(1)静的メソッド:別のクラスを使用して

public static void main(String[] args) { 
    int i = 14400; 
    while(true){ 
     int myResult = testRecursion(i); 
     System.out.println(myResult); 
     i++; 
    } 
} 

public static int testRecursion(int number) { 
    if (number == 1) { 
     return 1; 
    } else { 
     int result = 1 + testRecursion(number - 1); 
     return result; 
    }  
} 
//Exception in thread "main" java.lang.StackOverflowError after 62844 

(2)非静的メソッド:

public static void main(String[] args) { 
    int i = 14400; 
    while(true){  
     TestRecursion tr = new TestRecursion(); 
     int myResult = tr.testRecursion(i); 
     System.out.println(myResult); 
     i++; 
    } 
} 
//Exception in thread "main" java.lang.StackOverflowError after 14002 

テスト再帰クラスました唯一の方法としてpublic int testRecursion(int number) {

関連する問題