Frage Was verursacht einen java.lang.StackOverflowError


Was kann ein verursachen? java.lang.StackOverflowError? Der Stapelausdruck, den ich bekomme, ist nicht sehr tief (nur 5 Methoden).


76
2017-07-07 18:26


Ursprung


Antworten:


Suchen Sie nach irgendwelchen anrufenden Methodenaufrufen. Hauptsächlich wird es verursacht, wenn ein rekursiver Aufruf einer Methode stattfindet. Ein einfaches Beispiel ist

public static void main(String... args) {
    Main main = new Main();

    main.testMethod(1);
}

public void testMethod(int i) {
    testMethod(i);

    System.out.println(i);
}

Hier die System.out.println (i); Wird beim Aufruf von testMethod wiederholt zum Stack geschoben.


57
2017-07-08 10:01



Eines der (optionalen) Argumente für die JVM ist die Stapelgröße. Es ist -Xss. Ich weiß nicht, wie der Standardwert ist, aber wenn die Gesamtmenge an Material auf dem Stapel diesen Wert überschreitet, wird dieser Fehler angezeigt.

Im Allgemeinen ist eine unendliche Rekursion die Ursache dafür, aber wenn Sie das sehen würden, würde Ihr Stack-Trace mehr als 5 Frames haben.

Versuchen Sie, ein -Xss-Argument hinzuzufügen (oder den Wert von eins zu erhöhen), um zu sehen, ob das weggeht.


19
2017-07-07 18:29



Was tatsächlich einen java.lang.StackOverflowError verursacht, ist normalerweise eine unbeabsichtigte Rekursion. Für mich ist es oft, wenn ich eine Super-Methode für die Overidden-Methode aufrufen wollte. Wie in diesem Fall:

public class Vehicle {
    public void accelerate(float acceleration, float maxVelocity) {
        // set the acceleration
    }
}

public class SpaceShip extends Vehicle {
    @Override
    public void accelerate(float acceleration, float maxVelocity) {
        // update the flux capacitor and call super.accelerate
        // oops meant to call super.accelerate(acceleration, maxVelocity);
        // but accidentally wrote this instead. A StackOverflow is in our future.
        this.accelerate(acceleration, maxVelocity); 
    }
}

Zunächst ist es nützlich zu wissen, was hinter den Kulissen passiert, wenn wir eine Funktion aufrufen. Die Argumente und die Adresse, wo die Methode aufgerufen wurde, werden auf den Stack geschoben (siehe http://en.wikipedia.org/wiki/Stack_(abstract_data_type)#Runtime_memory_management), damit die aufgerufene Methode auf die Argumente zugreifen kann und die Ausführung nach dem Aufruf der Methode fortgesetzt werden kann. Aber da wir this.accelerate (accelerate, maxVelocity) rekursiv aufrufen (Rekursion ist lose, wenn sich eine Methode selbst aufruft). Für weitere Informationen siehe http://en.wikipedia.org/wiki/Recursion_(computer_science)) Wir befinden uns in einer Situation, die als unendliche Rekursion bekannt ist, und wir häufen die Argumente und die Adresse auf dem Aufruf-Stack. Da der Aufrufstapel in der Größe begrenzt ist, haben wir schließlich keinen Speicherplatz mehr. Das Überlaufen von Speicherplatz auf dem Aufrufstapel wird als Überlauf bezeichnet. Das liegt daran, dass wir versuchen, mehr Stapelspeicher zu verwenden, als wir haben, und die Daten überlaufen buchstäblich den Stapel. In der Programmiersprache Java führt dies zur Laufzeitausnahme java.lang.StackOverflow und stoppt das Programm sofort.

Das obige Beispiel ist etwas vereinfacht (obwohl es mir mehr passiert, als ich zugeben möchte). Das Gleiche kann in einer runderen Art passieren, was es ein bisschen schwieriger macht, es aufzuspüren. Im Allgemeinen ist der StackOverflow jedoch normalerweise ziemlich einfach zu beheben, sobald er auftritt.

Theoretisch ist es auch möglich, einen Stapelüberlauf ohne Rekursion zu haben, aber in der Praxis scheint es ein ziemlich seltenes Ereignis zu sein.


9
2018-06-20 03:35



Wenn ein Funktionsaufruf von einer Java-Anwendung aufgerufen wird, wird ein Stack-Frame auf dem Aufruf-Stack zugewiesen. Der Stack-Frame enthält die Parameter der aufgerufenen Methode, ihre lokalen Parameter und die Rückgabeadresse der Methode.

Die Rücksprungadresse bezeichnet den Ausführungspunkt, von dem die Programmausführung fortgesetzt werden soll, nachdem die aufgerufene Methode zurückgegeben wurde. Wenn kein Platz für einen neuen Stapelrahmen ist, dann wird der StackOverflowError wird von der geworfen Java Virtual Machine (JVM).

Der häufigste Fall, der möglicherweise den Stack einer Java-Anwendung erschöpft, ist Rekursion.

Bitte guck dir das an

Wie löst man StackOverflowError?


4
2017-09-28 12:05



Was ist java.lang.StackOverflowError

Der Fehler java.lang.StackOverflowError wird ausgelöst, um anzuzeigen, dass der Stapel der Anwendung wegen tiefer Rekursion erschöpft war, d. h. Ihr Programm / Skript rekursiert zu tief.

Einzelheiten

Das StackOverflowError erweitert VirtualMachineError Klasse, die anzeigt, dass der JVM Ressourcen zur Verfügung standen oder nicht mehr zur Verfügung stehen und nicht weiter betrieben werden können. Das VirtualMachineError was erweitert die Error Klasse wird verwendet, um auf die schwerwiegenden Probleme hinzuweisen, die eine Anwendung nicht erfassen sollte. Eine Methode deklariert solche Fehler möglicherweise nicht in ihrer throw Klausel, da diese Fehler abnormale Bedingungen sind, von denen nie erwartet wurde, dass sie auftreten.

Ein Beispiel

Minimal, Complete, and Verifiable Example :

package demo;

public class StackOverflowErrorExample {

    public static void main(String[] args) 
    {
        StackOverflowErrorExample.recursivePrint(1);
    }

    public static void recursivePrint(int num) {
        System.out.println("Number: " + num);

        if(num == 0)
            return;
        else
            recursivePrint(++num);
    }

}

Konsolenausgabe

Number: 1
Number: 2
.
.
.
Number: 8645
Number: 8646
Number: 8647Exception in thread "main" java.lang.StackOverflowError
    at java.io.FileOutputStream.write(Unknown Source)
    at java.io.BufferedOutputStream.flushBuffer(Unknown Source)
    at java.io.BufferedOutputStream.flush(Unknown Source)
    at java.io.PrintStream.write(Unknown Source)
    at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
    at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
    at sun.nio.cs.StreamEncoder.flushBuffer(Unknown Source)
    at java.io.OutputStreamWriter.flushBuffer(Unknown Source)
    at java.io.PrintStream.newLine(Unknown Source)
    at java.io.PrintStream.println(Unknown Source)
    at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:11)
    at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:16)
    .
    .
    .
    at demo.StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:16)

Erklärung

Wenn ein Funktionsaufruf von einer Java-Anwendung aufgerufen wird, a Stapelrahmen ist auf der zugewiesen Anrufliste. Das stack frame enthält die Parameter der aufgerufenen Methode, ihre lokalen Parameter und die Rückgabeadresse der Methode. Die Rücksprungadresse bezeichnet den Ausführungspunkt, von dem die Programmausführung fortgesetzt werden soll, nachdem die aufgerufene Methode zurückgegeben wurde. Wenn kein Platz für einen neuen Stapelrahmen ist, dann wird der StackOverflowError wird von der Java Virtual Machine (JVM) ausgelöst.

Der häufigste Fall, der möglicherweise den Stack einer Java-Anwendung erschöpft, ist Rekursion. Bei der Rekursion ruft sich eine Methode während ihrer Ausführung selbst auf. Recursion eine der mächtigsten Allzweck-Programmiertechnik, aber muss mit Vorsicht verwendet werden, um die StackOverflowError vermieden werden.

Verweise


4
2017-12-15 11:29



Ich habe ein Programm mit Hibernate erstellt, in dem ich zwei POJO-Klassen erstellt habe, beide mit einem Objekt als Datenmitglieder. Als ich in der Hauptmethode versuchte, sie in der Datenbank zu speichern, habe ich auch diesen Fehler bekommen.

Dies geschieht, weil beide Klassen sich gegenseitig beziehen und somit eine Schleife erzeugen, die diesen Fehler verursacht.

Überprüfen Sie also, ob solche Beziehungen in Ihrem Programm existieren.


2
2018-04-03 18:40



Stack Overflow-Ausnahmen können auftreten, wenn ein Thread-Stack bis zum Erreichen des Maximalwerts weiter anwächst.

Anpassen der Stapelgrößen (Xss und Xmso) Optionen ...

Ich schlage vor, Sie sehen diesen Link: http://www-01.ibm.com/support/docview.wss?uid=swg21162896 Es gibt viele mögliche Ursachen für einen StackOverflowError, wie Sie in der Verknüpfung sehen können ....


1
2017-09-02 12:05