Berapa kedalaman maksimum dari java call stack?


100

Seberapa dalam saya harus masuk ke tumpukan panggilan sebelum saya mendapatkan StackOverflowError? Apakah platform jawaban bergantung?



Karena ini adalah pertanyaan yang bagus, saya telah memperbarui judul menjadi sesuatu yang menurut saya lebih jelas terkait dengan artinya. (Sebelumnya saya pikir Anda mungkin mengacu pada kedalaman tumpukan tertentu yang Anda ambil saat runtime, misalnya). Jangan ragu untuk mengubahnya kembali jika Anda tidak setuju.
Andrzej Doyle

Jawaban:



31

Saya menguji sistem saya dan tidak menemukan nilai yang konstan, terkadang stack overflow terjadi setelah 8900 panggilan, terkadang hanya setelah 7700, nomor acak.

public class MainClass {

    private static long depth=0L;

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

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

}

15
Bukankah ini kasus bahwa ini adalah rekursif ekor dan tidak boleh meluap? Edit: Maaf. Di Jawa itu jatuh pada 8027; di Scala nilainya mencapai 8594755 sebelum saya bosan.
arya

9
@arya, bagian penting dari semantik JVM adalah rekursi ekor tidak didukung. Ini memberikan banyak masalah menarik bagi mereka yang ingin mengimplementasikan bahasa dengan rekursi ekor di JVM.
Thorbjørn Ravn Andersen

2
public foo() { try { foo(); } finally { foo(); } }dapat berjalan 'secara virtual' selamanya, di java saja.
Felype

bagi saya, StackOverflowErrorterjadi setelah 8792
ericdemo07

2
@ ThorbjørnRavnAndersen pengoptimalan rekursi ekor tidak didukung. Agak jelas Anda dapat memiliki rekursi ekor. Itu hanya tidak mengoptimalkannya untuk tidak menumbuhkan tumpukan panggilan.
ramping

19

Ukuran tumpukan dapat diatur dengan -Xsssaklar baris perintah tetapi sebagai aturan praktis, itu cukup dalam, ratusan jika tidak ribuan panggilan. (Standarnya bergantung pada platform, tetapi setidaknya 256k di sebagian besar platform.)

Jika Anda mendapatkan stack overflow, 99% waktunya disebabkan oleh kesalahan dalam kode.


3
1 untuk paragraf kedua. Orang harus selalu ingat tentang itu.
mcveat

6
Dengan eclipse, saya hanya mendapatkan 1024 panggilan rekursif.
Norswap

2
@Norswap Apakah Anda menentukannya dengan ukuran pelacakan tumpukan? Itu tampaknya dibatasi hingga 1024, terlepas dari ukuran sebenarnya dari tumpukan.
Brian McCutchon

4

Bandingkan dua panggilan ini:
(1) Metode statis:

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) Metode non-statis menggunakan kelas yang berbeda:

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

Uji kelas rekursi memiliki public int testRecursion(int number) {satu-satunya metode.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.