Was kann ein verursachen java.lang.StackOverflowError
? Der Stapelausdruck, den ich bekomme, ist überhaupt nicht sehr tief (nur 5 Methoden).
86
Was kann ein verursachen java.lang.StackOverflowError
? Der Stapelausdruck, den ich bekomme, ist überhaupt nicht sehr tief (nur 5 Methoden).
Antworten:
Suchen Sie nach wiederkehrenden Methodenaufrufen. Dies wird hauptsächlich verursacht, wenn eine Methode rekursiv aufgerufen wird. Ein einfaches Beispiel ist
Hier das System.out.println (i); wird wiederholt zum Stapeln verschoben, wenn die testMethod aufgerufen wird.
quelle
Eines der (optionalen) Argumente für die JVM ist die Stapelgröße. Es ist -Xss. Ich weiß nicht, was der Standardwert ist, aber wenn die Gesamtmenge des Materials auf dem Stapel diesen Wert überschreitet, wird dieser Fehler angezeigt.
Im Allgemeinen ist eine unendliche Rekursion die Ursache dafür. Wenn Sie dies jedoch sehen würden, hätte Ihre Stapelverfolgung mehr als 5 Frames.
Versuchen Sie, ein -Xss-Argument hinzuzufügen (oder den Wert von eins zu erhöhen), um festzustellen, ob dies nicht mehr funktioniert.
quelle
Was tatsächlich einen java.lang.StackOverflowError verursacht, ist normalerweise eine unbeabsichtigte Rekursion. Für mich ist es oft, wenn ich beabsichtigte, eine Supermethode für die überschriebene Methode aufzurufen. Wie in diesem Fall:
Zunächst ist es hilfreich zu wissen, was hinter den Kulissen passiert, wenn wir eine Funktion aufrufen. Die Argumente und die Adresse, an der die Methode aufgerufen wurde, werden auf den Stapel verschoben (siehe http://en.wikipedia.org/wiki/Stack_(abstract_data_type)#Runtime_memory_management ), damit die aufgerufene Methode auf die Argumente zugreifen kann und wann Wenn die aufgerufene Methode abgeschlossen ist, kann die Ausführung nach dem Aufruf fortgesetzt werden. Da wir this.accelerate (Beschleunigung, maxVelocity) rekursiv aufrufen (Rekursion ist lose, wenn sich eine Methode selbst aufruft. Weitere Informationen finden Sie unter http://en.wikipedia.org/wiki/Recursion_(computer_science).) Wir befinden uns in einer Situation, die als unendliche Rekursion bekannt ist, und stapeln die Argumente und die Rücksprungadresse auf dem Aufrufstapel. Da der Aufrufstapel endlich ist, geht uns schließlich der Speicherplatz aus. Der Platzmangel auf dem Aufrufstapel wird als Überlauf bezeichnet. Dies liegt daran, dass wir versuchen, mehr Stapelspeicher als wir zu verwenden, und die Daten den Stapel buchstäblich überlaufen. 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). Dasselbe kann auf eine rundere Art und Weise passieren, was es etwas schwieriger macht, es aufzuspüren. Im Allgemeinen ist der StackOverflow jedoch in der Regel recht einfach aufzulösen, sobald er auftritt.
Theoretisch ist es auch möglich, einen Stapelüberlauf ohne Rekursion zu haben, aber in der Praxis scheint dies ein ziemlich seltenes Ereignis zu sein.
quelle
Was ist
java.lang.StackOverflowError
Der Fehler
java.lang.StackOverflowError
wird angezeigt, um anzuzeigen, dass der Stapel der Anwendung aufgrund einer tiefen Rekursion erschöpft ist, dh Ihr Programm / Skript rekursiert zu tief.Einzelheiten
Die
StackOverflowError
Extended-VirtualMachineError
Klasse, die angibt, dass der JVM die Ressourcen ausgegangen sind oder ausgegangen sind und nicht weiter ausgeführt werden können. Das,VirtualMachineError
was dieError
Klasse erweitert, wird verwendet, um die schwerwiegenden Probleme anzuzeigen, die eine Anwendung nicht abfangen sollte. Eine Methode darf solche Fehler nicht deklarierenthrow
Klausel, da diese Fehler abnormale Bedingungen sind, von denen nie erwartet wurde, dass sie auftreten.Ein Beispiel
Minimal, Complete, and Verifiable Example
::Konsolenausgabe
Erklärung
Wenn ein Funktionsaufruf von einer Java - Anwendung aufgerufen wird, ein Stapelrahmen wird auf dem zugeordneten Call - Stack . Das
stack frame
enthält die Parameter der aufgerufenen Methode, ihre lokalen Parameter und die Rücksprungadresse der Methode. Die Rücksprungadresse gibt den Ausführungspunkt an, von dem aus die Programmausführung fortgesetzt werden soll, nachdem die aufgerufene Methode zurückgekehrt ist. Wenn kein Platz für einen neuen Stapelrahmen vorhanden ist, wird derStackOverflowError
wird dieser von der Java Virtual Machine (JVM) ausgelöst.Der häufigste Fall, der möglicherweise den Stapel einer Java-Anwendung erschöpfen kann, ist die Rekursion. Bei der Rekursion ruft sich eine Methode während ihrer Ausführung auf.
Recursion
eine der leistungsstärksten Allzweck-Programmiertechniken, die jedoch mit Vorsicht angewendet werden muss, damit dieStackOverflowError
damit dies vermieden wird.Verweise
quelle
Wenn ein Funktionsaufruf von einer Java-Anwendung aufgerufen wird, wird dem Aufrufstapel ein Stapelrahmen zugewiesen. Der Stapelrahmen enthält die Parameter der aufgerufenen Methode, ihre lokalen Parameter und die Rücksprungadresse der Methode.
Die Rücksprungadresse gibt den Ausführungspunkt an, von dem aus die Programmausführung fortgesetzt werden soll, nachdem die aufgerufene Methode zurückgekehrt ist. Wenn kein Platz für einen neuen Stack-Frame vorhanden ist, wird der StackOverflowError von der Java Virtual Machine (JVM) ausgelöst .
Der häufigste Fall, der möglicherweise den Stapel einer Java-Anwendung erschöpfen kann, ist die Rekursion.
Guck dir das mal bitte an
So lösen Sie StackOverflowError
quelle
Ich habe ein Programm mit Ruhezustand erstellt, in dem ich zwei POJO-Klassen erstellt habe, beide mit einem Objekt voneinander als Datenelemente. Als ich in der Hauptmethode versuchte, sie in der Datenbank zu speichern, bekam ich auch diesen Fehler.
Dies geschieht, weil beide Klassen aufeinander verweisen und somit eine Schleife erstellen, die diesen Fehler verursacht.
Überprüfen Sie also, ob in Ihrem Programm solche Beziehungen bestehen.
quelle
Lösung für Benutzer im Ruhezustand beim Parsen von Daten:
Ich hatte diesen Fehler, weil ich eine Liste von Objekten analysiert habe, die auf beiden Seiten
@OneToMany
und zugeordnet sind@ManyToOne
analysierte, die json mit jackson zugeordnet waren, was eine Endlosschleife verursachte.Wenn Sie sich in derselben Situation befinden, können Sie dies mithilfe von
@JsonManagedReference
und@JsonBackReference
Anmerkungen lösen .Definitionen aus der API:
JsonManagedReference ( https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonManagedReference.html ):
JsonBackReference: ( https://fasterxml.github.io/jackson-annotations/javadoc/2.5/com/fasterxml/jackson/annotation/JsonBackReference.html ):
Beispiel:
Owner.java:
Car.java:
Eine andere Lösung ist die Verwendung, bei
@JsonIgnore
der das Feld nur auf Null gesetzt wird.quelle
Stapelüberlauf-Ausnahmen können auftreten, wenn ein Thread-Stapel weiter an Größe zunimmt, bis die maximale Grenze erreicht ist.
Anpassen der Optionen für Stapelgrößen (Xss und Xmso) ...
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 im Link sehen können ....
quelle
In meinem Fall habe ich zwei Aktivitäten. In der zweiten Aktivität habe ich vergessen, die onCreate-Methode super zu setzen.
quelle
StackOverflowError
, tue ich nicht, dass es die Frage beantwortet. Ich denke, eine richtige Antwort sollte entweder andere Möglichkeiten auflisten, um diese Ausnahme zu erhalten, als zu viel Rekursion zu verwenden, oder sagen, dass es definitiv keine andere Möglichkeit gibt, eine solche Ausnahme zu erhalten, als sie manuell auszulösen.