530 Stimmen

Was ist ein StackOverflowFehler?

Was ist ein StackOverflowError Was sind die Ursachen dafür, und wie gehe ich damit um?

0 Stimmen

Die Stapelgröße in Java ist klein. Und manchmal, z.B. bei vielen rekursiven Aufrufen, steht man vor diesem Problem. Sie können Ihren Code durch Schleifen umgestalten. Ein allgemeines Entwurfsmuster dafür finden Sie auf dieser Seite: jndanial.com/73

0 Stimmen

Eine nicht offensichtliche Möglichkeit, dies zu erreichen: Fügen Sie die Zeile new Object() {{getClass().newInstance();}}; zu einem statischen Kontext (z. B. main Methode). Funktioniert nicht aus dem Instanzkontext heraus (wirft nur InstantiationException ).

7voto

Chris Jester-Young Punkte 212385

Wie Sie schon sagten, müssen Sie etwas Code zeigen :-)

Ein Stapelüberlauffehler tritt normalerweise auf, wenn Ihre Funktionsaufrufe zu tief verschachtelt sind. Siehe die Stack Overflow Code Golf Thread für einige Beispiele, wie dies geschieht (obwohl im Fall dieser Frage die Antworten absichtlich einen Stapelüberlauf verursachen).

1 Stimmen

Ich möchte auf jeden Fall Code hinzufügen, aber da ich nicht weiß, was Stapelüberläufe verursacht, bin ich nicht sicher, welchen Code ich hinzufügen soll. das Hinzufügen des gesamten Codes wäre lahm, nicht wahr?

0 Stimmen

Ist Ihr Projekt Open-Source? Wenn ja, erstellen Sie einfach ein Sourceforge- oder Github-Konto und laden Sie Ihren gesamten Code dort hoch :-)

0 Stimmen

Das klingt nach einer großartigen Idee, aber ich bin ein solcher Anfänger, dass ich nicht einmal weiß, was ich hochladen müsste. Die Bibliothek, die ich importiere, die Klassen, die ich erweitere usw... sind mir alle unbekannt. Oh Mann: schlechte Zeiten.

7voto

Rahul Sah Punkte 299

A StackOverflowError ist ein Laufzeitfehler in Java.

Er wird ausgelöst, wenn der von der JVM zugewiesene Speicherplatz im Aufrufstapel überschritten wird.

Ein häufiger Fall einer StackOverflowError wird ausgelöst, wenn der Aufrufstapel aufgrund einer zu tiefen oder unendlichen Rekursion überläuft.

Beispiel:

public class Factorial {
    public static int factorial(int n){
        if(n == 1){
            return 1;
        }
        else{
            return n * factorial(n-1);
        }
    }

    public static void main(String[] args){
         System.out.println("Main method started");
        int result = Factorial.factorial(-1);
        System.out.println("Factorial ==>"+result);
        System.out.println("Main method ended");
    }
}

Stapelverfolgung:

Main method started
Exception in thread "main" java.lang.StackOverflowError
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)
at com.program.stackoverflow.Factorial.factorial(Factorial.java:9)

Im obigen Fall kann dies durch programmatische Änderungen vermieden werden. Wenn die Programmlogik jedoch korrekt ist und das Problem trotzdem auftritt, muss der Stapel vergrößert werden.

6voto

Vikram Punkte 3802

StackOverflowError ist auf dem Stapel als OutOfMemoryError ist der Haufen.

Unbegrenzte rekursive Aufrufe führen dazu, dass der Stapelplatz aufgebraucht wird.

Das folgende Beispiel ergibt StackOverflowError :

class  StackOverflowDemo
{
    public static void unboundedRecursiveCall() {
     unboundedRecursiveCall();
    }

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

StackOverflowError ist vermeidbar, wenn rekursive Aufrufe begrenzt werden, um zu verhindern, dass die Gesamtsumme der unvollständigen speicherinternen Aufrufe (in Bytes) die Stapelgröße (in Bytes) übersteigt.

5voto

splattne Punkte 102178

Die häufigste Ursache für Stapelüberläufe ist übermäßig tiefe oder unendliche Rekursion . Wenn dies Ihr Problem ist, dieses Tutorium über Java Rekursion könnte helfen, das Problem zu verstehen.

5voto

Yiling Punkte 2629

Hier ist ein Beispiel für einen rekursiven Algorithmus zur Umkehrung einer einfach verknüpften Liste. Auf einem Laptop (mit den Spezifikationen 4 GB Speicher, Intel Kern i5 2,3 GHz CPU 64 bit und Windows 7), wird diese Funktion in StackOverflow Fehler für eine verknüpfte Liste der Größe in der Nähe von 10.000 laufen.

Ich will damit sagen, dass wir die Rekursion mit Bedacht einsetzen und dabei immer den Umfang des Systems berücksichtigen sollten.

Oft kann eine Rekursion in ein iteratives Programm umgewandelt werden, das besser skaliert. (Eine iterative Version desselben Algorithmus finden Sie am Ende der Seite. Sie kehrt eine einfach verkettete Liste der Größe 1 Million in 9 Millisekunden um).

private static LinkedListNode doReverseRecursively(LinkedListNode x, LinkedListNode first){

    LinkedListNode second = first.next;

    first.next = x;

    if(second != null){
        return doReverseRecursively(first, second);
    }else{
        return first;
    }
}

public static LinkedListNode reverseRecursively(LinkedListNode head){
    return doReverseRecursively(null, head);
}

Iterative Version desselben Algorithmus:

public static LinkedListNode reverseIteratively(LinkedListNode head){
    return doReverseIteratively(null, head);
}

private static LinkedListNode doReverseIteratively(LinkedListNode x, LinkedListNode first) {

    while (first != null) {
        LinkedListNode second = first.next;
        first.next = x;
        x = first;

        if (second == null) {
            break;
        } else {
            first = second;
        }
    }
    return first;
}

public static LinkedListNode reverseIteratively(LinkedListNode head){
    return doReverseIteratively(null, head);
}

0 Stimmen

Ich denke, dass es bei JVM eigentlich keine Rolle spielt, welche Spezifikationen Ihr Laptop hat.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X