Kiedyś myślałem, że tak nie jest, ale wczoraj musiałem to zrobić. Jest to aplikacja korzystająca z Akka (implementacja systemu aktorów dla JVM) do przetwarzania zadań asynchronicznych. Jeden z aktorów wykonuje pewne manipulacje PDF, a ponieważ biblioteka jest błędna, umiera StackOverflowErrorco jakiś czas.
Drugi aspekt polega na tym, że Akka jest skonfigurowane do zamykania całego systemu aktorów, jeśli zostanie wykryty błąd krytyczny JVM (np. StackOverflowError).
Trzecim aspektem jest to, że ten system aktorów jest osadzony w aplikacji internetowej (z powodu WTF, dziedzictwa, powodów), więc gdy system aktorów jest zamknięty, aplikacja internetowa nie. W efekcie StackOverflowErrornasza aplikacja do przetwarzania zadań staje się pustą aplikacją internetową.
Jako szybką poprawkę musiałem złapać StackOverflowErrorrzucanego, aby pula wątków systemu aktorów nie została zerwana. Doprowadziło mnie to do wniosku, że może czasem dobrze jest wyłapać takie błędy, szczególnie w takich kontekstach? Kiedy pula wątków przetwarza dowolne zadania? W przeciwieństwie do OutOfMemoryErrornie mogę sobie wyobrazić, jak a StackOverflowErrormoże pozostawić aplikację w niespójnym stanie. Stos jest usuwany po takim błędzie, więc obliczenia mogą przebiegać normalnie. Ale może brakuje mi czegoś ważnego.
Pamiętajmy też, że przede wszystkim jestem za naprawieniem błędu (tak naprawdę kilka dni temu naprawiłem już SOE w tej samej aplikacji), ale tak naprawdę nie wiem, kiedy to może powstać taka sytuacja.
Dlaczego lepiej byłoby zrestartować proces JVM zamiast łapać StackOverflowError, oznaczyć to zadanie jako nieudane i kontynuować moją działalność?
Czy jest jakiś ważny powód, aby nigdy nie łapać SOE? Z wyjątkiem „najlepszych praktyk”, które są niejasnym terminem, który nic mi nie mówi.
StackOverflowExceptions są zwykle spowodowane nie kończącym się łańcuchem wywołań metod - zwiększenie przestrzeni stosu zwiększyłoby wówczas koszt pamięci nowego wątku bez żadnej korzyści.
:-)