Vorrei sapere come vengono allocate le variabili locali in javascript. In C e C++ le variabili locali sono memorizzate nello stack. È lo stesso in javascript? o tutto è immagazzinato nell'heap?In che modo le variabili sono allocate in memoria in Javascript?
risposta
In realtà è un'area molto interessante di Javascript. Dettagli in the spec, ma: il modo in cui Javascript gestisce le variabili locali è molto diverso dal modo in cui C lo fa. Quando si chiama una funzione, tra le altre cose viene creato un "ambiente variabile" per quella chiamata, che ha qualcosa chiamato "oggetto vincolante". (Chiamalo "oggetto variabile" in breve, dicendo "l'oggetto vincolante dell'ambiente variabile" è solo un tad bit prolisso!) L'oggetto variabile ha proprietà per gli argomenti della funzione, tutte le variabili locali dichiarato nella funzione e tutte le funzioni dichiarate all'interno della funzione (insieme ad un paio di altre cose). I riferimenti non qualificati (ad esempio, il foo
in foo
, non obj.foo
) all'interno della funzione sono prima verificata l'oggetto variabile per vedere se corrispondono proprietà su di esso; se lo fanno, vengono utilizzate quelle proprietà.
Quando una chiusura sopravvive alla funzione di ritorno (che può accadere per diversi motivi), l'oggetto variabile per quella chiamata di funzione è trattenuto nella memoria dal riferimento dalla chiusura. A prima vista, ciò suggerirebbe che lo stack non venga utilizzato per le variabili locali; infatti, i moderni motori JavaScript sono abbastanza intelligenti, e possono (se ne vale la pena) utilizzare lo stack per i locali che non vengono effettivamente utilizzati dalla chiusura. (Naturalmente, lo stack è ancora usato per tenere traccia di indirizzi di ritorno e così via.)
Ecco un esempio:
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"
Quando chiamiamo foo
, un oggetto variabile viene creato con queste proprietà:
a
eb
— gli argomenti della funzionec
— una variabile locale dichiarata nella funzionebar
— una funzione dichiarata all'interno della funzione- (... e un paio di altre cose)
Quando foo
esegue l'istruzione c = a + b;
, è riferimento le c
, a
e b
proprietà sull'oggetto variabile per tale chiamata a foo
. Quando foo
restituisce un riferimento alla funzione bar
dichiarata al suo interno, bar
sopravvive la chiamata a foo
ritorno. Dal momento che ha un bar
(nascosto) riferimento all'oggetto variabile per quella specifica chiamata a foo
, l'oggetto variabile sopravvive (mentre nel caso normale, non avrebbe alcun riferimenti in sospeso e quindi sarebbe disponibile per la garbage collection).
Più tardi, quando chiamiamo bar
, un nuovo oggetto variabile per tale chiamata viene creato con (tra le altre cose) una proprietà chiamata d
— l'argomento bar
.I riferimenti non qualificati all'interno di bar
vengono prima verificati rispetto all'oggetto variabile per quella chiamata; per esempio, d
risolve la proprietà d
sull'oggetto variabile per la chiamata a bar
. Ma un riferimento non qualificato che non corrisponde a una proprietà sul suo oggetto variabile viene quindi confrontato con l'oggetto variabile successivo nella "catena di ambito" per bar
, che è l'oggetto variabile per la chiamata a foo
. E dal momento che ha una proprietà c
, questa è la proprietà utilizzata all'interno di bar
. Per esempio, in termini grezzi:
+----------------------------+ | `foo` call variable object | | -------------------------- | | a = 1 | | b = 2 | | c = 3 | | bar = (function) | +----------------------------+ ^ | chain | +----------------------------+ | `bar` call variable object | | -------------------------- | | d = 3 | +----------------------------+
Implementazioni sono liberi di utilizzare qualsiasi meccanismo che vogliono sotto le coperte per fare il sopra sembrano per accadere. È impossibile ottenere un accesso diretto all'oggetto variabile per una chiamata di funzione, e la specifica chiarisce che è perfettamente soddisfacente se l'oggetto variabile è solo un concetto, piuttosto che una parte letterale dell'implementazione. Una semplice implementazione potrebbe benissimo fare letteralmente quello che dice la specifica; uno più complicato può usare una pila quando non ci sono chiusure coinvolte (per il beneficio della velocità), o può sempre usare una pila ma poi "strappare" l'oggetto variabile necessario per una chiusura quando fa scoppiare la pila. L'unico modo per sapere in un caso specifico è guardare il loro codice. :-)
Ulteriori su chiusura, la catena di portata, ecc qui:
Grazie. Chiusura finita. – Anshul
Cos'è un riferimento non qualificato? – LazerSharks
@Gnuey: 'foo' in' foo' ma non in 'obj.foo', che è qualificato con' obj'. –
Purtroppo la risposta è: dipende.
C'è stato un grande cambiamento nei recenti motori javascript che hanno iniziato a ottimizzare molto meglio di prima. La risposta era: "Le variabili locali sono archiviate in frame stack allocati all'heap per far funzionare le chiusure". Non è più così semplice.
C'è stato (o usato come 20-30 anni fa) la ricerca per le implementazioni dello schema e l'ottimizzazione della chiusura (JavaScript ha ereditato praticamente le chiusure di Scheme, eccetto per le continuazioni che lo rendono ancora più complicato).
Non ho i collegamenti della carta pronti, ma se non si dispone di un garbage collector incredibilmente efficiente è necessario utilizzare anche lo stack. La parte delicata è quindi la gestione delle chiusure, che devono avere le allocazioni di heap delle variabili. Per questo si usano strategie diverse.Il risultato è un ibrido in cui:
- da funzioni inline, è possibile ridurre il numero di fotogrammi heap allocata essere allocato/deallocato significativamente
- alcune variabili possono essere messi in sicurezza sulla pila, in quanto è il momento della vita è limitato (è spesso collegato all'inallinare anche le chiamate di funzione)
- in alcuni casi si sa che si potrebbe creare la chiusura, ma è possibile attendere fino a che ciò accada e quindi allocare lo stack stack-frame per esso e copiare i valori correnti dallo stack
- ci sono ottimizzazioni connesse alle code-call, dove è possibile allocare l'heap in precedenza e quindi riutilizzarlo e stack frame per la prossima chiamata di funzione, ma non è usato nei motori javascript per quanto ne so attualmente
questo campo sta cambiando molto velocemente in diversi motori concorrenti, quindi la risposta probabilmente sarà ancora "dipende "
Inoltre, nelle nuove versioni del linguaggio vedremo funzionalità come let
e const
che rendono davvero più facile per i motori ottimizzare le decisioni di allocazione. Soprattutto l'immutabilità aiuta moltissimo, dal momento che è possibile copiare i valori liberamente dallo stack (e rendere quindi parte dell'oggetto di chiusura, ad esempio) senza risolvere le collisioni di variabili variabili da chiusure diverse.
Grazie mille! Allora, dove posso imparare queste cose oltre a postare domande qui? Proviene dalla lettura di motori allo stato dell'arte (i loro documenti e persino il codice sorgente) o dallo scavare nei documenti di ricerca? Sono particolarmente interessato alle strategie di ottimizzazione che hai menzionato. Dove posso trovare i dettagli su di loro? Grazie ancora! – dacongy
personalmente, il più influente per me è stata questa dissertazione di un guru dello schema Kent Dybvig http://www.cs.unm.edu/~williams/cs491/three-imp.pdf e ci sono alcuni documenti specialistici/dettagliati basati su in alto. Inoltre, ho visto di recente molte cose interessanti che descrivono gli attuali motori JavaScript e il progresso che i team stanno facendo in questo modo http://wingolog.org/archives/2011/07/05/v8-a-tale-of-two -compilatori ma di solito non vanno troppo in profondità. –
il link originale (nella home page dell'autore) è http://www.cs.indiana.edu/~dyb/pubs/3imp.pdf –
- 1. In che modo vengono implementate le variabili dell'interfaccia in Go?
- 2. In che modo Rust sposta le variabili dello stack che non sono copiabili?
- 3. In quale oggetto sono memorizzate le variabili globali di Javascript?
- 4. Le variabili sono "scopate" staticamente o dinamicamente in javascript?
- 5. In che modo le CPU Intel Xeon scrivono in memoria?
- 6. In che modo le risorse sono ascoltanti in java?
- 7. C'è un modo per passare le variabili javascript in url?
- 8. In che modo JavaScript gestisce le risposte AJAX in background?
- 9. In che modo le applicazioni HTML5/JavaScript in stile Metro WinRT sono pacchettizzate e protette
- 10. In che modo le funzioni del prototipo sono diverse dalle normali funzioni in javascript?
- 11. In che modo esattamente PHP raggiunge le variabili "dinamiche"?
- 12. Come ridimensionare le regioni allocate da VirtualAlloc?
- 13. Dove sono memorizzate le variabili in Python?
- 14. Le strutture vengono sempre allocate o talvolta allocate?
- 15. In che modo Java gestisce gli oggetti stringa in memoria?
- 16. In che modo le chiusure creano perdite di memoria?
- 17. In che modo ptr_vector gestisce la memoria?
- 18. Dove sono le variabili costanti memorizzate in C?
- 19. In che modo JavaScript rileva le espressioni regolari?
- 20. In che modo le funzioni di HoG sono rappresentate graficamente?
- 21. variabili django in javascript
- 22. Quali sono tutti i modi per allocare la memoria in C e in che modo differiscono?
- 23. Come utilizzare le variabili statiche in modo efficiente?
- 24. In che modo spray trova le risorse, ad es. javascript
- 25. In che modo Javascript gestisce le chiamate ricorsive?
- 26. Le funzioni in coda JavaScript sono ottimizzate?
- 27. In che modo il DOS carica un programma in memoria?
- 28. In che modo gli oggetti Java sono disposti in memoria su Android?
- 29. In che modo JavaScript associa eventi WinRT?
- 30. Come si eseguono le variabili scalari in memoria?
possibile duplicato di [JavaScript ha un heap di memoria?] (Http://stackoverflow.com/questions/1026495/does-javascript-have-a-memory-heap) –
Vedi questo articolo, [A Tour of V8 : object object] (http://www.jayconrod.com/posts/52/a-tour-of-v8-object-representation) che fornisce una panoramica di come il motore Javascript V8 rappresenta oggetti Javascript. –
@RichardChambers: Grazie per il link piacevole. –