Comment gérer StackOverflowError en Java?
Comment gérer StackOverflowError
en Java ?
Crash. C'est ce que je fais toujours.
Merci de poster le code qui est à l'origine du débordement de la pile. En évitant les débordements de pile sont presque toujours mieux que d'essayer de traiter l'exception.
Ahh, l'ironie de cette question sur un site internet avec ce nom...
Arrêter le débordement de la pile.
Jeter à StackOverflow.com Vous avez manipulé StackOverflowError correctement, en publiant sur StackOverflow!!!
Merci de poster le code qui est à l'origine du débordement de la pile. En évitant les débordements de pile sont presque toujours mieux que d'essayer de traiter l'exception.
Ahh, l'ironie de cette question sur un site internet avec ce nom...
Arrêter le débordement de la pile.
Jeter à StackOverflow.com Vous avez manipulé StackOverflowError correctement, en publiant sur StackOverflow!!!
OriginalL'auteur Silent Warrior | 2009-06-04
Vous devez vous connecter pour publier un commentaire.
Je ne suis pas sûr de ce que tu veux dire avec "poignée".
Vous pouvez certainement rattraper cette erreur:
mais c'est probablement une mauvaise idée, sauf si vous savez exactement ce que vous faites.
Vous avez probablement un problème grave dans votre programme. Évaluer la trace de la pile et de vérifier si vous trouvez quelque chose de suspect. Vous pouvez continuer après la capture de la StackOverflowError parce que la pile a été vidé par la levée d'erreur... je ne peux que me répéter: il est de trouver le bug qui cause le problème!
Maumau, c'est un StachOverflowError, pas StackOverflowException, la différence étant que le nom de "ERREUR" indique qu'il ne doit pas être pris par try...catch, mais vous devez réécrire votre code comme moi et la plupart des autres, voici ce qui suggère.
il n'y a pas une telle chose comme un stach overflow
Pacerier, C'est une faute de frappe.
OriginalL'auteur Huxi
Vous avez probablement un peu de récursivité infinie passe.
I. e. une méthode qui s'appelle elle-même maintes et maintes
Un de le gérer est de corriger votre code afin que la récurrence s'arrête au lieu de continuer pour toujours.
+1 pour le nom de la méthode. Aussi: KnightsWhoSayNeet()
OriginalL'auteur Andrew Bullock
Prendre un coup d'oeil à Raymond Chenaprès Lors du débogage d'un débordement de pile, vous voulez vous concentrer sur la répétition de partie récursive. Un extrait:
OriginalL'auteur Michael Myers
Vous pourriez vouloir voir si le "Xss" option est prise en charge par votre JVM. Si oui, vous voudrez peut-être essayer un réglage à une valeur de 512k (la valeur par défaut est de 256 ko de moins de 32-bits de Windows et Unix) et de voir si cela ne fait rien (autre que de vous faire siéger plus longtemps jusqu'à ce que votre StackOverflowException). Notez que c'est par thread, donc si vous avez beaucoup de threads en cours d'exécution, vous pourriez aussi vouloir remonter votre tas de paramètres.
OriginalL'auteur TMN
La réponse correcte est celle déjà donnée. Vous avez probablement un) ont un bug dans votre code conduisant à une récursion infinie qui est généralement assez facile à diagnostiquer et à résoudre, ou b) ont un code qui peut conduire à de très profondes récurrences par exemple parcourant récursivement un déséquilibre arbre binaire. Dans ce dernier cas, vous devez modifier votre code pour ne pas allouer les informations sur la pile (c'est à dire à ne pas répéter), mais au lieu de le répartir dans le tas.
Par exemple, pour un déséquilibre de l'arbre transversal, vous pouvez stocker les nœuds qui devront être revues dans une Pile de structure de données. Pour une commande traversée de vous boucle vers le bas la gauche branches poussent chaque nœud comme vous l'avez visité jusqu'à ce que vous frappez une feuille, ce qui vous permettrait de processus, puis de la pop un nœud sur le dessus de la pile, de la traiter, puis redémarrez votre boucle avec le droit de l'enfant (il suffit de régler votre variable de boucle à droite du nœud.) Cela permettra d'utiliser une quantité constante de la pile en déplaçant tout ce qui était sur la pile sur le tas dans la Pile de structure de données. Tas est généralement beaucoup plus abondant que la pile.
Comme quelque chose qui est généralement une très mauvaise idée, mais elle est nécessaire dans les cas où l'utilisation de la mémoire est très limitée, vous pouvez utiliser le pointeur de la reprise. Dans cette technique, vous encodez la pile dans la structure que vous traversez, et en réutilisant les liens que vous traversez, vous pouvez le faire avec pas ou beaucoup moins de la mémoire supplémentaire. En utilisant l'exemple ci-dessus, au lieu de pousser les noeuds lorsque l'on boucle, nous avons juste besoin de nous souvenir de nos parent immédiat, et à chaque itération, nous avons mis le lien, nous avons traversé le parent actuel, puis le courant parent du nœud de nous quitter. Quand on arrive à une feuille, nous les traitons, puis aller à notre parent et puis nous avons une énigme. Nous ne savons pas si pour corriger la branche gauche, processus de ce nœud, et continuer avec la branche de droite, ou de corriger la branche de droite et accédez à nos parents. Nous avons donc besoin d'allouer un supplément de peu de renseignements que nous itération. Typiquement, pour le faible niveau de réalisation de cette technique, peu seront stockées dans le pointeur lui-même aucune mémoire supplémentaire et constante de la mémoire globale. Ce n'est pas une option en Java, mais il peut être possible de conserver ce bit dans les champs utilisés pour d'autres choses. Dans le pire des cas, c'est toujours au moins 32 ou 64 fois une réduction de la quantité de mémoire nécessaire. Bien sûr, cet algorithme est très facile de se tromper avec complètement déroutante résultats et pose de proférer des ravages avec la concurrence. Il est donc presque jamais la peine de l'entretien cauchemar sauf si l'allocation de mémoire est intenable. L'exemple typique étant un garbage collector où les algorithmes de ce type sont en commun.
Ce que je voulais vraiment en parler, cependant, c'est lorsque vous souhaitez gérer le StackOverflowError. À savoir fournir queue appel à l'élimination de la JVM. Une approche consiste à utiliser le trampoline de style où au lieu d'effectuer un appel tail vous retourner un nullary procédure d'objet, ou si vous êtes juste de retour d'une valeur à votre retour. [Note: ceci nécessite des moyens de dire une fonction retourne Une ou B. En Java, sans doute le plus léger façon de le faire est de retourner un type normalement et jeter l'autre comme une exception à la règle.] Alors à chaque fois que vous appelez une méthode, vous devez faire une boucle while de l'appel de la nullary procédures (qui eux-mêmes renvoient une nullary procédure ou d'une valeur) jusqu'à obtenir une valeur. Une boucle sans fin va devenir une boucle while qui est constamment forcer procédure d'objets que la procédure de retour des objets. Les avantages de trampoline style, c'est qu'il n'utilise qu'un facteur constant de plus de pile que vous utilisez avec une mise en œuvre correctement éliminé tous les appels tail, il utilise le Java normal de la pile pour les non-queue appels, la traduction simple, et il ne pousse le code par un (fastidieux) facteur constant. L'inconvénient est que vous allouer un objet sur chaque appel de méthode (qui deviendra immédiatement la poubelle) et la consommation de ces objets implique un couple indirects appels par queue d'appel.
L'idéal chose à faire serait de ne jamais affecter ces nullary procédures ou d'autre chose, en premier lieu, ce qui est exactement ce que la queue d'appel d'élimination permettrait de réaliser. Travailler avec ce que Java fournit un bien, ce que nous pourrions faire est d'exécuter le code comme normal et ne rendre ces nullary procédures quand nous sommes à court de pile. Maintenant il nous reste allouer ces inutile de cadres, mais nous le faisons sur la pile plutôt que le tas et de libérer en vrac, également, nos appels sont normales direct Java appels. La meilleure façon de décrire cette transformation est d'abord de réécrire toutes les multi-appel-déclaration des méthodes en méthodes qui ont deux états, c'est à dire fgh() { f(); g(); h(); } devient fgh() { f(); gh(); } et gh(){ g(); h(); }. Pour des raisons de simplicité, je vais assumer toutes les méthodes à la fin de la queue d'appel, qui peuvent être organisées par l'empaquetage de le reste d'une méthode dans une méthode distincte, même si dans la pratique, vous souhaitez gérer directement. Après ces transformations, nous avons trois cas, une méthode a zéro appels auquel cas il n'y a rien à faire, ou il en a un (de la queue) appeler, dans ce cas, nous l'envelopper dans un bloc try-catch dans la même, nous allons pour la queue d'appel dans les deux cas. Enfin, il peut avoir deux appels, un non-queue appel et une queue appeler, dans ce cas, nous appliquons la transformation suivante illustré par l'exemple (à l'aide de C#lambda notation qui pourrait facilement être remplacé par un anonyme intérieure, avec un peu de croissance):
Le principal avantage ici est que si aucune exception n'est levée, c'est le même code que nous avons commencé avec des gestionnaires d'exception installé. Depuis la queue d'appels (h ()) n'est pas gérer le Rebond exception, cette exception sera volée par le biais de leur déroulement (inutile) des images à partir de la pile. Le non-queue appels attraper le Rebond des exceptions et à renvoyer avec le reste du code ajouté. Cela permettra de vous détendre de la pile tout le chemin jusqu'au niveau le plus haut, l'élimination de la queue d'appel des cadres, mais de se souvenir de la non-appel tail images dans le nullary procédure. Lorsque nous avons finalement exécuter la procédure dans le Rebond de l'exception au niveau supérieur, nous allons recréer tous les non-queue appel des cadres. À ce point, si nous avons immédiatement exécuter hors de la pile à nouveau, alors, puisque nous ne sommes pas réinstaller le StackOverflowError gestionnaires, il ira uncaught comme souhaité, car nous sommes vraiment hors de la pile. Si nous obtenons un peu plus loin, un nouveau StackOverflowError sera installé en tant que de besoin. En outre, si nous faisons des progrès, mais ensuite, exécutez hors de la pile de nouveau, il n'y a aucun avantage de re-déroulage les images que nous avons déjà déroulé, nous avons donc installer de nouveaux haut-niveau des gestionnaires de sorte que la pile ne sera bloqué jusqu'à eux.
Le plus gros problème avec cette approche est que vous aurez probablement envie d'appel normal méthodes de Java et vous pouvez avoir arbitrairement peu d'espace de pile lorsque vous le faites, il peut donc y avoir suffisamment d'espace pour commencer mais pas fini et vous ne pouvez pas reprendre dans le milieu. Il y a au moins deux solutions à cela. La première est d'envoyer tous ces travaux à un thread séparé qui aura son propre pile. C'est assez efficace et assez facile et n'allons pas introduire de la concurrence (sauf si vous le souhaitez.) Une autre option est de simplement délibérément détendre la pile avant l'appel à la normale de la méthode en Java par tout simplement jeter un StackOverflowError immédiatement avant eux. Si c'est toujours à court d'espace de pile lorsque vous sortez, vous ont été vissées pour commencer.
Une chose semblable peut être fait pour rendre les continuations de juste-à-temps. Malheureusement, cette transformation n'est pas vraiment supportable à faire à la main en Java, et est probablement à la limite pour des langages comme C# ou Scala. Ainsi, les transformations, comme cette tendance à faire par des langues qui cible la JVM et non par des gens.
OriginalL'auteur Derek Elkins
Je suppose que vous ne pouvez pas - ou au moins dépend de la machine que vous utilisez. Un débordement de pile signifie, que vous n'avez pas de place pour stocker les variables locales et les adresses de retour. Si votre jvm ne certaine forme de compilation, vous avez la stackoverflow dans la jvm ainsi et cela signifie que vous ne pouvez pas le manipuler ou de le rattraper. La jvm a pour résilier.
Il pourrait y avoir un moyen de créer une machine qui permet un tel comportement, mais il est lent.
Je n'ai pas testé le comportement avec la jvm, mais dans .net vous ne pouvez pas gérer la stackoverflow. Même try catch ne va pas aider. Depuis java et .net reposent sur le même concept (machines virtuelles avec jit) je soupçonne de java devrait se comporter de la même. La présence d'un stackoverflow-exception .NET le suggère, il pourrait y avoir une vm qui n'activer le programme pour l'attraper, le normal n'est pas bien.
OriginalL'auteur Tobias Langner
Plus de chances d'obtenir des
StackOverflowError
à l'aide de [/infini] récurrences dans une des fonctions récursives.Vous pouvez éviter Fonction de la récursivité par l'évolution de la conception de votre application pour utiliser empilables objets de données. Il y a des modèles de codage pour convertir récursive codes à itératif des blocs de code. Regardez ci-dessous answeres:
Ainsi, vous évitez la mémoire de l'empilement par Java pour votre récessive appels de fonction, en utilisant vos propres données piles.
OriginalL'auteur Chand Priyankara
La trace de la pile doit indiquer la nature du problème. Il devrait y avoir quelques évident en boucle lorsque vous lisez la trace de la pile.
Si ce n'est pas un bug, vous avez besoin d'ajouter un compteur ou d'un autre mécanisme d'arrêt de la récursion avant la récursivité est si profonde qu'il provoque un débordement de pile.
Un exemple de cela pourrait être si vous êtes la manipulation de XML imbriquée dans un modèle DOM avec les appels récursifs et le XML est imbriquée si profonde qu'il provoque un débordement de pile avec vos appels imbriqués (peu probable, mais possible). Cela devrait être assez profonde imbrication de provoquer un débordement de pile.
OriginalL'auteur Neal Maloney
Comme mentionné par beaucoup dans ce fil, la cause commune pour c'est une méthode récursive d'appel qui n'a pas de fin. Si possible, éviter le débordement de la pile et si vous le tester vous devez prendre cela en considération dans la plupart des cas un sérieux problème. Dans certains cas, vous pouvez configurer la taille de la pile en Java pour être plus grand pour traiter certaines circonstances ( grands ensembles de données sont gérées dans le local de la pile de stockage, de longs appels récursifs), mais cela permettra d'accroître l'ensemble de la mémoire, ce qui peut conduire à des problèmes dans le nombre de threads disponibles dans la machine virtuelle. En général, si vous obtenez cette exception le thread local et de données à ce fil devrait être considéré comme toast et n'est pas utilisé( c'est à dire suspect et peut-être endommagé).
OriginalL'auteur VHF
Simple,
Regarder la trace de la pile que le StackOverflowError produit si vous savez où dans votre code, il se produit et de l'utiliser pour comprendre comment réécrire le code pour qu'il ne demande pas lui-même de manière récursive (probablement la cause de votre erreur) de sorte qu'il ne se reproduise pas.
StackOverflowErrors ne sont pas quelque chose qui doit être traité par l'intermédiaire d'un try...catch de la clause, mais il indique un défaut de base dans la logique de votre code qui doit être fixé par vous.
OriginalL'auteur Avrom
java.lang.Erreur javadoc:
Une Erreur est une sous-classe de Throwable qui indique des problèmes graves qu'une application raisonnable ne devrait pas essayer de l'attraper. La plupart de ces erreurs sont des conditions anormales. Le ThreadDeath erreur, si un "normal", est également une sous-classe de message d'Erreur, car la plupart des applications ne devraient pas essayer de l'attraper.
Une méthode n'est pas tenu de déclarer, dans son jette clause de toutes les sous-classes d'Erreur qui peut être levée lors de l'exécution de la méthode, mais pas pris, car ces erreurs sont des conditions anormales qui ne devrait jamais se produire.
Donc, ne pas. Essayez de trouver ce qui ne va pas dans la logique de votre code. Cette exception apparaît très souvent à cause de la récursivité infinie.
OriginalL'auteur jpangamarca
dans certaines circonstances, vous ne pouvez pas attraper stackoverflowerror. chaque fois que vous essayez, vous rencontrerez de nouveaux. parce que c'est la machine virtuelle java. il est bon de trouver récursive de blocs de code, comme Andrew Bullock dit.
OriginalL'auteur ferhatozkanun
Cependant, vous pouvez avoir un coup d'oeil sur le lien: http://marxsoftware.blogspot.in/2009/07/diagnosing-and-resolving.html pour comprendre l'extrait de code, ce qui peut augmenter erreur
OriginalL'auteur Vikram