web-dev-qa-db-fra.com

Est-ce que c'est * toujours * d'accord pour attraper Stackoverflowerror en Java?

Je pensais que ce n'est pas le cas, mais hier, je devais le faire. C'est une application qui utilise AKKA (mise en œuvre du système acteur pour la JVM) pour traiter les travaux asynchrones. L'un des acteurs exécute certains PDF manipulation, et parce que la bibliothèque est buggy, elle meurt avec un StackOverflowError de temps en temps.

Le deuxième aspect est que AKKA est configuré pour arrêter son système d'acteur entier si une erreur fatale JVM (E.g. Stackoverflowerror) est prise.

Le troisième aspect est que ce système acteur est intégré à une application Web (pour WTF-ISH, legacy, les raisons), de sorte que lorsque le système Acteur est arrêté, l'application Web n'est pas. L'effet net est que sur un StackOverflowError notre application de traitement de travail ne devient qu'une application Web vide.

En tant que solution rapide, je devais attraper le StackOverflowError étant jeté, de sorte que le bassin de fil du système d'acteur n'est pas déchiré. Cela me conduit à penser que peut-être qu'il est parfois correct d'attraper de telles erreurs, en particulier dans des contextes comme celui-ci? Quand il y a un traitement de piscine de fil 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, le calcul peut donc continuer normalement. Mais peut-être que je manque quelque chose d'important.

Aussi, il est à noter que je suis tout à fait pour résoudre l'erreur en premier lieu (en fait, j'ai déjà réparé une SOE dans cette même application il y a quelques jours), mais je ne sais vraiment pas quand cela une sorte de situation pourrait survenir.

Pourquoi serait-il préférable de redémarrer le processus JVM au lieu d'attraper le StackOverflowError, marquez ce travail comme étant échoué et continuez avec mon entreprise?

Y a-t-il une raison convaincante de ne jamais attraper des entreprises d'épense? Sauf "Meilleures pratiques", qui est un terme vague qui ne me dit rien.

27
Ionuț G. Stan

En règle générale, si c'était Absolument jamais, jamais acceptable de faire quelque chose, et il y avait un accord à ce sujet, les responsables de la langue n'auraient pas permis de cela. Il n'y a presque pas de telles maxims coupées à l'unanimité. (Heureusement, parce que c'est ce qui garde les programmeurs humains américains dans des emplois!)

Cela ressemble beaucoup à ce que vous ayez trouvé une situation où attraper cette erreur est la meilleure option pour vous: elle permet à votre demande de fonctionner, tandis que toutes les autres alternatives ne le font pas, et c'est ce qui compte à la fin. Toutes les "meilleures pratiques" sont simplement des sommations de longues expériences avec de nombreux cas pouvant habituellement être utilisé à la place d'une analyse détaillée d'un cas spécifique pour gagner du temps ; Dans votre cas, vous avez déjà effectué l'analyse spécifique et obtenu un résultat différent. Félicitations, vous êtes capable d'une pensée indépendante!

(Cela dit, il existe sûrement des situations où un débordement de pile pourrait laisser une application incompatible, comme une épuisement de la mémoire. Imaginez simplement que certains objets sont construits et ensuite initialisés à l'aide d'appels de méthode interne imbriqués - si l'un d'entre eux jette, l'objet peut très bien être dans un état non censé être possible, tout comme si une allocation avait échoué. Mais cela ne signifie pas que votre solution ne pourrait toujours pas être la meilleure.)

44
Kilian Foth

Je ne sais pas s'il y a des risques spécifiques à la JVM ici, mais dans l'ensemble, il semble assez judicieux.

Par exemple, il existe des algorithmes récursifs, comme Naif Quicksort, qui ont log(n) la profondeur de pile dans un cas typique, mais dans le pire des cas, ils se dégradent à la profondeur n qui peut faire sauter la pile.

Le pire des cas est rare et il est peu probable que vous redémarrez si vous redémarrez de trier sur l'ensemble partiellement trité, il a donc beaucoup de sens pour attraper une exception de dépassement de pile lorsqu'elle se produit et redémarrez des travaux au lieu d'essayer d'éviter toute erreur de se produire ou de faire la mort. Toute application.

2
Kornel