Nur neugierig. In an answer über das Abfangen von StackOverflowErrors schrieb jemand: "Sicher gibt es Situationen, in denen ein Stapelüberlauf eine Anwendung inkonsistent wie eine Speichererschöpfung machen könnte". Was ist das Besondere an StackOverflowErrors, dass sie den Anwendungsstatus mehr als beispielsweise eine NullPointerException im Falle eines Fehlers zu beschädigen drohen? Eine Sache, an die ich denken kann ist, dass ein StackOverflowError an Orten auftreten kann, wo normalerweise niemals eine Ausnahme (oder eine andere Throwable) geworfen wird (z.B. ein einfacher Getter), so dass das Programm wahrscheinlich nicht darauf vorbereitet ist. Gibt es teuflischere Probleme?Welchen Schaden hat ein StackOverflowError?
Antwort
Ein Stapelüberlauffehler bedeutet überhaupt nicht, dass der Speicher erschöpft ist und macht an sich nichts inkonsistentes.
Aber ein Stapelüberlauffehler ist normalerweise ein Fehler. Sie sollten den Fehler beheben, anstatt die Ausnahme abzufangen. Verwenden Sie das Ausnahmesystem nicht zum Ausblenden von Fehlern.
Auch wenn Sie wissen, dass das Risiko eines zu tiefen Stapels besteht (Graphexploration zum Beispiel), gibt es bessere Möglichkeiten, das zu kontrollieren, als den Stack explodieren zu lassen.
Von the Javadoc of the Error superclass:
Ein Fehler ist eine Unterklasse von Throwable, die ernsthafte Probleme zeigt an, dass eine vernünftige Anwendung sollte nicht zu fangen versuchen. Die meisten dieser Fehler sind abnormale Bedingungen. Der ThreadDeath-Fehler, obwohl eine "normale" Bedingung, ist auch eine Unterklasse von Fehler, da die meisten Anwendungen nicht versuchen sollten, es zu fangen.
Lustige Sache ist ... Sie können diesen Fehler tatsächlich nicht fangen. Die VM stürzt ab, bevor Sie etwas tun können. –
@PaulNikonowicz - Eigentlich können Sie es fangen ... wenn Ihre JVM ordnungsgemäß implementiert ist. Sie müssen es nur so weit abfangen, dass genügend Stapelspeicher zur Verfügung steht, um das auszuführen, was der Handler tun muss. –
Auch wenn es wirklich ein OutOfMemoryError war - warum würde das irgendetwas inkonsistentes machen - mehr als jeder andere Fehler, der zu einer Ausnahme führt? Übrigens: In einer anständigen Anwendung müssen Sie alles - einschließlich Fehler - irgendwo auf der obersten Ebene der Anwendung abfangen, um zu vermeiden, dass der Endbenutzer mit einem Stacktrace konfrontiert wird, und vielleicht eine Fehlerprotokollierung und Fehlerberichterstattung. –
Ein Fehler ist ein ernstes Problem, das nicht deshalb gefangen werden sollten: auch nicht fangen die Superklasse (Throwable) wenn eine Methode einen Fehler wirft Sie müssen nicht erklären, eine wirft-Klausel
Das Verhalten einer Anwendung ist oft nach einem Fehler nicht vorhersehbar - Fehler zeigen eine anormale Bedingung an
Wenn also ein StackOverflowError geworfen wurde, erreichte die Anwendung das Maximum an Stack-Plätzen für jetzt. Sie könnten Ihre Anwendung erneut überprüfen, um z. der Müllsammler früher.
Danke für die Antwort. Ich verstehe nicht, was der Müllsammler damit zu tun hat. Wie auch immer - meine Frage war, ob das SOE schlimmere Konsequenzen haben kann, als ich in der Frage angedeutet habe. –
Ich denke, dass eine SOE in der Regel aufgrund von Codierungsfehler statt Datenfehler passieren wird. Andere Kommentare sagen "Ein Stapelüberlauffehler ist normalerweise ein Fehler", ist aber normalerweise auch keine NPE? –
@ user2310289 Es gibt viele Möglichkeiten, auf eine NPE zu stoßen, so viele, dass Sie vielleicht einige Tests überspringen und sich manchmal auf das try/catch-System verlassen sollten. Aber ja, eine NPE zu fangen sollte auch selten sein. –
Beachten Sie, dass es ein Fehler ist! keine Ausnahme! –