Je voudrais savoir comment les variables locales sont allouées en javascript. En C et C++, les variables locales sont stockées sur la pile. Est-ce la même chose en javascript? ou tout est stocké dans le tas?Comment les variables sont allouées de la mémoire en Javascript?
Répondre
C'est en fait un domaine très intéressant de Javascript. Détails dans the spec, mais: la façon dont Javascript gère les variables locales est très différente de la façon dont C le fait. Quand vous appelez une fonction, entre autres choses, un "environnement variable" est créé pour cet appel, qui a quelque chose appelé "objet de liaison". (Appelez le "objet variable" pour faire court, dire "l'objet de liaison de l'environnement variable" est juste tad bit à long terme!) L'objet variable a propriétés pour les arguments de la fonction, toutes les variables locales déclaré dans la fonction, et toutes les fonctions déclarées dans la fonction (avec quelques autres choses). Les références non qualifiées (par exemple, foo
dans foo
, et non obj.foo
) dans la fonction sont d'abord vérifiées par rapport à l'objet variable pour voir si elles correspondent aux propriétés de ce dernier; s'ils le font, ces propriétés sont utilisées.
Lorsqu'une fermeture survit à la fonction return (ce qui peut se produire pour plusieurs raisons), l'objet variable pour cet appel de fonction est conservé en mémoire par la référence de la fermeture. À première vue, cela suggère que la pile n'est pas utilisée pour les variables locales; en fait, les moteurs JavaScript modernes sont assez intelligents et peuvent (si cela en vaut la peine) utiliser la pile pour les locaux qui ne sont pas réellement utilisés par la fermeture. (Bien entendu, la pile est toujours utilisé pour garder la trace des adresses de retour et autres.)
Voici un exemple:
function foo(a, b) {
var c;
c = a + b;
function bar(d) {
alert("d * c = " + (d * c));
}
return bar;
}
var b = foo(1, 2);
b(3); // alerts "d * c = 9"
Lorsque nous appelons foo
, un objet variable est créé avec ces propriétés:
a
etb
— les arguments de la fonctionc
— une variable locale déclarée dans la fonctionbar
— une fonction déclarée dans la fonction- (... et quelques autres)
Lorsque foo
exécute l'instruction c = a + b;
, il est le référencement les propriétés c
, a
et b
sur l'objet variable pour cet appel à foo
. Lorsque foo
renvoie une référence à la fonction bar
déclarée à l'intérieur, bar
survit à l'appel à foo
renvoyant. Puisque bar
a une référence (cachée) à l'objet variable pour cet appel spécifique à foo
, l'objet variable survit (alors que dans le cas normal, il n'aurait aucune référence en suspens et serait donc disponible pour la récupération de place).
Plus tard, quand nous appelons bar
, un nouvel objet variables pour cet appel est créé avec (entre autres) une propriété appelée d
— l'argument bar
.Les références non qualifiées au sein de bar
sont d'abord vérifiées par rapport à l'objet variable pour cet appel; Par exemple, d
résout à la propriété d
sur l'objet variable pour l'appel à bar
. Mais une référence non qualifiée qui ne correspond pas à une propriété sur son objet variable est ensuite vérifiée par rapport à l'objet variable suivant dans la "chaîne de portée" pour bar
, qui est l'objet variable pour l'appel à foo
. Et puisque cela a une propriété c
, c'est la propriété utilisée dans bar
. Par exemple, en termes rugueux:
+----------------------------+ | `foo` call variable object | | -------------------------- | | a = 1 | | b = 2 | | c = 3 | | bar = (function) | +----------------------------+ ^ | chain | +----------------------------+ | `bar` call variable object | | -------------------------- | | d = 3 | +----------------------------+
Implémentations sont libres d'utiliser le mécanisme qu'ils veulent sous les couvertures pour rendre le ci-dessus semblent arriver. Il est impossible d'obtenir un accès direct à l'objet variable pour un appel de fonction, et la spécification indique clairement que c'est parfaitement bien si l'objet variable est juste un concept, plutôt qu'une partie littérale de l'implémentation. Une implémentation simple peut très bien faire littéralement ce que dit la spécification; un plus compliqué peut utiliser une pile quand il n'y a pas de fermetures impliquées (pour le gain de vitesse), ou peut toujours utiliser une pile mais ensuite "arracher" l'objet variable nécessaire pour une fermeture lors de l'éclatement de la pile. La seule façon de savoir dans un cas spécifique est de regarder leur code. :-)
En savoir plus sur les fermetures, la chaîne de portée, etc. ici:
Merci.Finally compris la fermeture. – Anshul
Qu'est-ce qu'une référence non qualifiée? – LazerSharks
@Gnuey: Le 'foo' dans' foo' mais pas dans 'obj.foo', qui est qualifié avec' obj.'. –
la réponse est Unfortunatelly: Cela dépend.
Il y avait un grand changement dans les moteurs JavaScript récents qui ont commencé à optimiser beaucoup mieux que par le passé. La réponse était: "Les variables locales sont stockées dans des trames de pile allouées par tas pour que les fermetures fonctionnent". Ce n'est plus si simple. Il y a eu (ou était il y a 20 ou 30 ans) des recherches sur les implémentations de schémas et l'optimisation des fermetures (JavaScript a hérité à peu près de fermetures de Scheme, sauf pour les suites qui le rendent encore plus compliqué).
Je n'ai pas les liens papier prêts, mais si vous n'avez pas de récupérateur de place incroyablement efficace, vous devez également utiliser la pile. La partie délicate concerne alors les fermetures, qui doivent avoir des variables allouées par tas. Pour cela différentes stratégies sont utilisées.Le résultat est un hybride où:
- par des fonctions inline, vous pouvez réduire le nombre de trames alloué-tas étant alloué/deallocated considérablement
- certaines variables peuvent être mis en sécurité sur la pile, car il est temps de vie est limited (il est souvent connecté à la fonction Inline)
- Dans certains cas, vous savez que vous êtes en train de créer une fermeture, mais vous pouvez attendre jusqu'à ce que cela se produise, puis lui allouer une pile-frame et copier les valeurs actuelles à partir de la pile
- Il existe des optimisations connectées aux appels de queue, où vous pouvez répartir le tas plus tôt, puis réutiliser. e pile frame pour l'appel de fonction suivante, mais qui n'est pas utilisé dans les moteurs javascript pour autant que je sache actuellement
ce champ change très rapidement dans plusieurs moteurs concurrents, donc la réponse sera probablement toujours "cela dépend En outre, dans les nouvelles versions du langage, nous verrons des fonctionnalités telles que let
et const
qui facilitent réellement les décisions d'allocation des moteurs. En particulier, l'immuabilité est très utile, car vous pouvez copier des valeurs librement hors de la pile (et faire alors partie de l'objet de fermeture par exemple) sans résoudre les collisions de variables changeantes de différentes fermetures.
Merci beaucoup! Alors, où puis-je apprendre ce genre de choses en plus d'afficher des questions ici? Est-ce en lisant des moteurs à la fine pointe de la technologie (leurs documents et même le code source) ou en cherchant des documents de recherche? Je suis particulièrement intéressé par les stratégies d'optimisation que vous avez mentionnées. Où puis-je trouver des détails à leur sujet? Merci encore! – dacongy
Personnellement, le plus influent pour moi était cette dissertation d'un régime gourou Kent Dybvig http://www.cs.unm.edu/~williams/cs491/three-imp.pdf et il y a quelques documents plus spécialisés/détaillés sur la base de en haut. En outre, j'ai vu récemment beaucoup de choses intéressantes décrivant les moteurs JavaScript actuels et les progrès que les équipes font comme celui-ci http://wingolog.org/archives/2011/07/05/v8-a-tale-of-two -compilers mais ils ne vont généralement pas trop loin. –
le lien d'origine (dans la page d'accueil de l'auteur) est http://www.cs.indiana.edu/~dyb/pubs/3imp.pdf –
- 1. Comment les variables d'octets sont-elles stockées en mémoire?
- 2. android: où sont les ressources d'image allouées?
- 3. Où en mémoire sont les variables stockées en C++?
- 4. Variables statiques dans les fonctions en C++ - allouées même si la fonction ne s'exécute pas?
- 5. structures de données allouées statiques
- 6. Comment les pages physiques sont-elles allouées et libérées pendant l'appel malloc et l'appel gratuit?
- 7. Obtenir les régions de mémoire allouées du processus en cours d'exécution
- 8. Comment Visual Studio détermine-t-il l'ordre dans lequel les variables de pile doivent être allouées?
- 9. libération de la mémoire de la variable locale en JavaScript
- 10. Comment lire les variables de l'application tierce depuis la mémoire?
- 11. Les variables de la fonction sont indéfinies
- 12. Exécution de la fonction Javascript après variables sont définies
- 13. Littéraux de chaîne dans les fonctions: variables automatiques ou allouées dans le tas?
- 14. Conversion de variables python en variables javascript
- 15. Quelles sont les variables initialisées en Delphi?
- 16. Où sont stockées les méthodes en mémoire?
- 17. suivi de la mémoire par programmation en Java
- 18. Variables de mémoire Java regex
- 19. Comment les @ "Strings" sont-ils alloués en mémoire?
- 20. Maintien des variables en mémoire, C++
- 21. Comment les caractères ASCII sont-ils stockés en mémoire?
- 22. Comment effacer un objet de la mémoire en utilisant JavaScript
- 23. javascript les variables
- 24. affectation de la mémoire des variables locales
- 25. Comment initialiser les variables membres en JavaScript avec l'héritage protoypal
- 26. Où sont utilisés les algorithmes de gestion de la mémoire?
- 27. Réutilisation de la mémoire en C++
- 28. Comment créer des variables dynamiccally en JavaScript
- 29. Comment l'allocation de mémoire est-elle effectuée pour les variables dans les langages de script?
- 30. Toutes les variables de fonction sont globales
duplication possible de [Est-ce que JavaScript a un tas de mémoire?] (Http://stackoverflow.com/questions/1026495/does-javascript-have-a-memory-heap) –
Voir cet article, [A Tour of V8 : représentation d'objet] (http://www.jayconrod.com/posts/52/a-tour-of-v8-object-representation) qui fournit un aperçu de la façon dont le moteur Javascript V8 représente les objets Javascript. –
@RichardChambers: Merci pour le gentil lien. –