84 votes

Limite de taille de la pile Javascript du navigateur

Je rencontre des problèmes de débordement de pile Javascript côté client, en particulier dans le navigateur IE, Cela se passe à l'intérieur d'une bibliothèque tierce qui fait des appels de fonction et pour une raison quelconque, ils se bloquent occasionnellement dans IE seulement en raison de sa faible limite de pile.

J'ai ensuite codé un petit test HTML pour tester la limite de la taille de la pile pour certains navigateurs et j'ai constaté que IE8 a en fait une petite limite de pile si on le compare à FF 7 ou Chrome 14 fonctionnant sur un ordinateur portable avec Windows 7 OS, 8Gb RAM :

<html>
<body>

<!-- begin Script: -->
<script type="text/javascript">

function doSomething(){

  var i = 3200;
  doSomethingElse(i);

}

function doSomethingElse(i){
  if (i == 0) return -1;
  doSomethingElse(i-1);
}

doSomething(); 

</script>
<!-- END OF PAGE -->

</body>
</html>

IE soulève un débordement de pile lorsque les valeurs sont autour de 3200, Firefox et Chrome peuvent gérer une récursion très profonde si on les compare à IE.

J'aimerais savoir s'il existe un moyen de lier l'exception de débordement de pile avec la fonction Javascript qui l'a soulevée pendant l'exécution dans IE ou tout autre navigateur et s'il est possible de donner la trace de la pile avec la chaîne de fonction dans la pile au moment où l'erreur a été soulevée.

2 votes

3200 appels, c'est beaucoup d'espace pour la pile. Les programmeurs Python (enfin, ceux qui ne s'acharnent pas à écrire des analyseurs récursifs ou à remplacer des boucles parfaitement simples par de la récursion pour le plaisir) se débrouillent très bien avec une limite de 1000 appels. Que faites-vous ?

4 votes

Il n'est pas formulé strictement en mode interrogatif, mais la dernière phrase "Je me demande s'il y a ..." pourrait être commencée par "Y a-t-il" et terminée par un point d'interrogation, ce qui donnerait une question assez directe.

0 votes

Merci pour les commentaires, je vais mieux clarifier la question.

153voto

josh3736 Points 41911

En utilisant un test simple :

var i = 0;
function inc() {
  i++;
  inc();
}

try {
  inc();
}
catch(e) {
  // The StackOverflow sandbox adds one frame that is not being counted by this code
  // Incrementing once manually
  i++;
  console.log('Maximum stack size is', i, 'in your current browser');
}

Internet Explorer

  • IE6 : 1130
  • IE7 : 2553
  • IE8 : 1475
  • IE9 : 20678
  • IE10 : 20677

Mozilla Firefox

  • 3.6 : 3000
  • 4.0 : 9015
  • 5.0 : 9015
  • 6.0 : 9015
  • 7.0 : 65533
  • 8b3 : 63485
  • 17 : 50762
  • 18 : 52596
  • 19 : 52458
  • 42 : 281810
  • 89 : 10746
  • 91 : 26441

Google Chrome

  • 14 : 26177
  • 15 : 26168
  • 16 : 26166
  • 25 : 25090
  • 47 : 20878
  • 51 : 41753
  • 93 : 13903

Safari

  • 4 : 52426
  • 5 : 65534
  • 9 : 63444
  • 14 : 45606

Safari iOS

  • 15 : 7909

Opéra

  • 10.10 : 9999
  • 10.62 : 32631
  • 11 : 32631
  • 12 : 32631
  • 78 : 13908

Bordure

  • 87 : 13970
  • 93 : 13903

Yandex

  • 21 : 13909

En ce qui concerne votre question, utilisez les outils de développement de votre navigateur pour voir la pile. Dans IE 8+, tapez F12 Allez dans l'onglet script et cliquez sur Start Debugging. Il se cassera quand une exception est lancée, et vous pouvez voir la pile d'appels. Vous pouvez également utiliser les outils de développement de Chrome, Ctrl + Shift + J .

7 votes

Vous pouvez aussi utiliser F12 pour Chrome

1 votes

Avec test jsfiddle.net/9YMDF/show J'ai ~21000 pour Chrome 28, 26000..53000 pour Firefox 20+, et ~3000 pour IE10 sous Windows 7 SP1 64-bit. Opera 12.X a une profondeur de pile assez proche de 32768. Et j'ai trouvé une installation malheureuse d'IE8 avec une profondeur de pile égale à 276 !

0 votes

Vous pouvez comparer ces résultats avec le BrowserScope lié ici

7voto

Nikoloff Points 1542

C'est spécifique au navigateur, pas seulement la taille de la pile, mais aussi les optimisations, des choses comme l'optimisation de la récursion de queue et d'autres choses. Je pense que la seule chose fiable ici est de coder d'une manière qui ne met pas des tonnes de choses dans la pile, ou de tester manuellement (en lisant profondément la documentation de) chaque navigateur. Après tout, lorsque vous voyez l'erreur "too much recursion" ou similaire, vous savez déjà qu'il y a quelque chose de vraiment mauvais dans votre code.

0 votes

Le TCO est-il vraiment réalisé en JavaScript ? J'ai lu que l'ES6 pourrait être pris en charge, mais je ne pense pas qu'il ait encore été mis en œuvre.

0 votes

Le TCO se cache derrière un drapeau dans Chrome pour le moment (deux implémentations différentes sont en cours d'évaluation). Je ne connais pas de navigateur qui l'implémente par défaut.

1 votes

@JanusTroelsen : ES2015 ("ES6") exige en effet que les moteurs fassent TCO. V8 l'a, mais l'équipe V8 ne le considère pas encore comme "stable" donc vous devez l'activer. (V8 classe les fonctionnalités qu'ils ont lancées comme "shipping" [terminé], "stable" et "in progress". TCO reste "en cours" mais les bases sont là pour les trois générateurs de code de V8. Je pense qu'ils ne l'ont pas encore promu au rang de "stable" parce qu'ils sont encore en train d'optimiser/trouver/réparer les bugs. Plus d'informations ici : stackoverflow.com/a/30369729/157247 )

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