Je pensais que non, mais hier, je devais le faire. Il s'agit d'une application qui utilise Akka (une implémentation de système d'acteur pour la JVM) pour traiter les travaux asynchrones. L'un des acteurs effectue une manipulation PDF, et parce que la bibliothèque est boguée, elle meurt de StackOverflowError
temps en temps.
Le deuxième aspect est qu'Akka est configuré pour arrêter tout son système d'acteurs si une erreur fatale JVM (par exemple StackOverflowError) est détectée.
Le troisième aspect est que ce système d'acteur est intégré dans une application Web (pour WTF-ish, héritage, raisons), donc lorsque le système d'acteur est arrêté, l'application Web ne l'est pas. L'effet net est que sur StackOverflowError
notre application de traitement des travaux devient juste une application Web vide.
En guise de solution rapide, j'ai dû attraper le StackOverflowError
lancer, afin que le pool de threads du système d'acteurs ne soit pas démoli. Cela m'amène à penser que c'est peut-être parfois correct de détecter de telles erreurs, en particulier dans des contextes comme celui-ci? Lorsqu'il existe un pool de threads traitant des tâches arbitraires? Contrairement à un, OutOfMemoryError
je ne peux pas imaginer comment un StackOverflowError
peut laisser une application dans un état incohérent. La pile est effacée après une telle erreur, donc le calcul peut continuer normalement. Mais peut-être que je manque quelque chose d'important.
De plus, notons que je suis tout à fait d'accord pour corriger l'erreur en premier lieu (en fait, j'ai déjà corrigé un SOE dans cette même application il y a quelques jours), mais je ne sais vraiment pas quand cela genre de situation pourrait survenir.
Pourquoi serait-il préférable de redémarrer le processus JVM au lieu de le rattraper StackOverflowError
, de marquer ce travail comme ayant échoué et de poursuivre mon entreprise?
Y a-t-il une raison impérieuse de ne jamais attraper les entreprises publiques? Sauf «meilleures pratiques», qui est un terme vague qui ne me dit rien.
StackOverflowException
s sont généralement dus à une chaîne non terminale d'appels de méthode - augmenter l'espace de la pile augmenterait alors le coût de la mémoire d'un nouveau thread sans aucun avantage.
:-)