Ce qui peut conduire à java.lang.StackOverflowError? La pile impression que je reçois n'est pas très profonde (seulement 5 méthodes).
Réponses
Trop de publicités?Vérifiez tout recusive appels de méthodes. Principalement, il est causé quand il y a appel récursif pour une méthode. Un exemple simple est
public static void main(String... args) {
Main main = new Main();
main.testMethod(1);
}
public void testMethod(int i) {
testMethod(i);
System.out.println(i);
}
Ici le Système..println(i); sera à plusieurs reprises poussé à pile quand l'testMethod est appelé.
L'un des (en option) les arguments de la JVM est la taille de la pile. C'est -Xss. Je ne sais pas ce que la valeur par défaut est, mais si le montant total des trucs sur la pile dépasse cette valeur, vous obtiendrez cette erreur.
Généralement, une récursion infinie est la cause de cela, mais si vous voyiez cela, votre trace de la pile aurait plus que 5 images.
Essayez d'ajouter un -Xss argument (ou l'augmentation de la valeur de l'un) pour voir si cela va loin.
Ce fait provoque une java.lang.StackOverflowError est généralement involontaire de la récursivité. Pour moi, c'est souvent quand j'ai l'intention de remettre une super méthode pour la overidden méthode. Comme dans ce cas:
public class Vehicle {
public void accelerate(float acceleration, float maxVelocity) {
// set the acceleration
}
}
public class SpaceShip extends Vehicle {
@Override
public void accelerate(float acceleration, float maxVelocity) {
// update the flux capacitor and call super.accelerate
// oops meant to call super.accelerate(acceleration, maxVelocity);
// but accidentally wrote this instead. A StackOverflow is in our future.
this.accelerate(acceleration, maxVelocity);
}
}
Tout d'abord, il est utile de savoir ce qui se passe derrière les coulisses, quand on appelle une fonction. Les arguments et l'adresse de l'endroit où la méthode a été appelée est poussé sur la pile (voir http://en.wikipedia.org/wiki/Stack_(abstract_data_type)#Runtime_memory_management), de sorte que la méthode appelée pouvez accéder aux arguments et que, lorsque la méthode appelée est terminée, l'exécution peut se poursuivre après l'appel. Mais puisque nous sommes à l'appel de cette.accélérer(accélération, maxVelocity) de manière récursive (récursivité est vaguement lorsqu'une méthode appelle elle-même. Pour plus d'info voir http://en.wikipedia.org/wiki/Recursion_(computer_science)) nous sommes dans une situation connue sous le nom de récursivité infinie et nous garder à empiler les arguments et l'adresse de retour sur la pile d'appel. Depuis la pile d'appel est limitée en taille, on finit par manquer d'espace. Le fonctionnement de l'espace sur la pile d'appel est connu en tant que dépassement de. C'est parce que nous essayons d'utiliser plus d'espace de pile que nous avons et les données littéralement des débordements de la pile. Dans le langage de programmation Java, cela aboutit à l'exception d'exécution java.lang.StackOverflow et arrêter immédiatement le programme.
L'exemple ci-dessus est quelque peu simplifiée (bien qu'il m'arrive plus que je ne voudrais l'admettre.) La même chose peut se produire en un tour de plus au sujet de manière rend un peu plus difficile à traquer. Cependant, en général, la StackOverflow est généralement assez facile à résoudre, une fois qu'il se produit.
En théorie, il est également possible d'avoir un débordement de la pile sans la récursivité, mais dans la pratique, il semblerait que c'était un événement assez rare.
J'ai créé un programme avec mise en veille prolongée, dans lequel j'ai créé deux classes POJO, à la fois avec un objet uns les autres comme les membres de données. Lorsque dans la méthode main, j'ai essayé de les enregistrer dans la base de données j'ai aussi eu cette erreur.
Cela se produit parce que les deux classes se réfèrent les uns aux autres, créant ainsi une boucle, ce qui provoque cette erreur.
Donc, vérifiez si l'un de ces types de relations existent dans votre programme.