Früher dachte ich, dass es nicht so ist, aber gestern musste ich es tun. Es ist eine Anwendung, die Akka (eine Implementierung des Aktorsystems für die JVM) verwendet, um asynchrone Jobs zu verarbeiten. Einer der Schauspieler führt eine PDF-Manipulation durch, und da die Bibliothek fehlerhaft ist, stirbt sie mitunter mit einem StackOverflowError
.
Der zweite Aspekt ist, dass Akka so konfiguriert ist, dass das gesamte Aktorsystem heruntergefahren wird, wenn ein schwerwiegender JVM-Fehler (z. B. StackOverflowError) festgestellt wird.
Der dritte Aspekt ist, dass dieses Darstellersystem in eine Web-App eingebettet ist (aus WTF-Gründen, Legacy-Gründen). Wenn das Darstellersystem heruntergefahren wird, ist dies bei der Web-App nicht der Fall. Der Nettoeffekt ist, dass StackOverflowError
unsere Jobbearbeitungsanwendung nur noch eine leere Webanwendung ist.
Als schnelle Lösung musste ich das StackOverflowError
Geworfene auffangen , damit der Threadpool des Darstellersystems nicht abgerissen wird. Das ließ mich denken, dass es vielleicht manchmal in Ordnung ist, solche Fehler zu fangen, besonders in solchen Kontexten? Wenn es einen Thread-Pool gibt, der beliebige Aufgaben verarbeitet? Im Gegensatz zu einem OutOfMemoryError
kann ich mir nicht vorstellen, wie StackOverflowError
man eine Anwendung in einem inkonsistenten Zustand belassen kann. Nach einem solchen Fehler wird der Stapel gelöscht, sodass die Berechnung normal fortgesetzt werden kann. Aber vielleicht fehlt mir etwas Wichtiges.
Es sei auch angemerkt, dass ich alles dafür bin, den Fehler an erster Stelle zu beheben (tatsächlich habe ich bereits vor einigen Tagen einen SOE in derselben App behoben), aber ich weiß wirklich nicht, wann dies geschieht Art von Situation kann auftreten.
Warum ist es besser, den JVM-Prozess neu zu starten, anstatt den StackOverflowError
Job abzufangen, als fehlgeschlagen zu markieren und mit meinem Geschäft fortzufahren?
Gibt es einen zwingenden Grund, SOEs niemals zu fangen? Mit Ausnahme von "Best Practices", einem vagen Begriff, der mir nichts sagt.
StackOverflowException
s sind normalerweise auf eine nicht abschließende Kette von Methodenaufrufen zurückzuführen. Wenn Sie den Stapelspeicherplatz erhöhen, erhöhen sich die Speicherkosten eines neuen Threads, ohne dass dies von Vorteil ist.
:-)