102 votes

Pourquoi est-ce possible de récupérer d’une StackOverflowError ?

Je suis surpris de voir comment il est possible de poursuivre l'exécution, même après un StackOverflowError a eu lieu en Java.

Je sais qu' StackOverflowError est un sublass de la classe d'Erreur. La classe d'Erreur est decumented comme "une sous-classe de Throwable qui indique des problèmes graves qu'une application raisonnable ne devrait pas essayer de l'attraper."

Ceci ressemble plus à une recommandation que d'une règle, sous-tendant que d'attraper un message d'Erreur semblable à un StackOverflowError est en fait autorisé et c'est au programmeur du caractère raisonnable de ne pas le faire. Et de voir, j'ai testé ce code, et il se termine normalement.

public class Test
{
    public static void main(String[] args)
    {
        try {
            foo();
        } catch (StackOverflowError e) {
            bar();
        }
        System.out.println("normal termination");
    }

    private static void foo() {
        System.out.println("foo");
        foo();
    }

    private static void bar() {
        System.out.println("bar");
    }
}

Comment cela peut-il être? Je pense que par moment le StackOverflowError est levée, la pile doit être si plein qu'il n'y a pas de place pour l'appel d'une autre fonction. Est l'erreur du bloc de gestion de l'exécution dans une autre pile, ou ce qui se passe ici?

121voto

delnan Points 52260

Lorsque les débordements de pile et de l' StackOverflowError est levée, l'habitude de la manipulation d'exception se déroule de la pile. Dépiler signifie:

  • interrompre l'exécution de la fonction
  • supprimer son cadre de pile, de procéder à l'appel de la fonction
  • interrompre l'exécution de l'appelant
  • supprimer son cadre de pile, de procéder à l'appel de la fonction
  • et ainsi de suite...

... jusqu'à ce que l'exception est interceptée. Ce qui est normal (en fait, nécessaire) et indépendant de l'exception est levée, et pourquoi. Puisque vous intercepter l'exception à l'extérieur du premier appel d' foo(), les milliers d' foo pile d'images qui a rempli la pile ont tous été déroulé et que la plupart de la pile est libre d'être utilisé à nouveau.

23voto

user2357112 Points 37737

Lorsque le StackOverflowError est levée, la pile est pleine. Cependant, quand il est pris, tous les appels ont été dépilés de la pile. peut fonctionner normalement parce que la pile est débordant de ne plus `` s. (Notez que je ne pense pas que le JLS garantit que vous pouvez récupérer depuis un débordement de pile comme ça.)

12voto

Nicolas Defranoux Points 1938

Lorsque le StackOverFlow se produit, la machine virtuelle Java descendra à la capture, libérant la pile.

Dans votre exemple, il récupère tous les objets empilés.

8voto

jmoreno Points 6995

Parce que la pile ne fait pas de débordement. Un meilleur nom, peut-être AttemptToOverflowStack. Fondamentalement, ce que cela signifie, c'est que la dernière tentative pour régler le cadre de la pile se trompe, car il n'y a pas assez d'espace libre restant sur la pile. La pile peut effectivement avoir beaucoup d'espace à gauche, juste pas assez d'espace. Donc, quelle que soit l'opération aurait dépendait de l'appel réussir (généralement un appel de méthode), n'est jamais exécutée et tout ce qui reste est pour le programme de composer avec cette réalité. Ce qui signifie qu'il est vraiment pas différent de toute autre exception. En fait, vous pourriez attraper l'exception de la fonction qui est de faire l'appel.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X