Heim  >  Artikel  >  Web-Frontend  >  Einführung in die JavaScript-Speicherverwaltung_Javascript-Kenntnisse

Einführung in die JavaScript-Speicherverwaltung_Javascript-Kenntnisse

WBOY
WBOYOriginal
2016-05-16 16:09:40906Durchsuche

Einführung

Low-Level-Sprachen wie C verfügen über Low-Level-Speicherverwaltungsprimitive wie malloc() und free(). Die Speicherprimitive von JavaScript hingegen werden beim Erstellen von Variablen (Objekten, Zeichenfolgen usw.) zugewiesen und dann „automatisch“ freigegeben, wenn sie nicht mehr verwendet werden. Letzteres wird Garbage Collection genannt. Diese „Automatik“ ist verwirrend und vermittelt den Entwicklern von JavaScript (und anderen Hochsprachen) die Illusion, dass sie sich keine Gedanken über die Speicherverwaltung machen müssen.

Speicherlebenszyklus

Unabhängig von der Programmiersprache ist der Speicherlebenszyklus grundsätzlich derselbe:

1. Weisen Sie den Speicher zu, den Sie benötigen
2. Benutze es (lesen, schreiben)
3. Lassen Sie es los, wenn es nicht verwendet wird. PS: Es hat die gleiche Bedeutung wie „einen Elefanten in den Kühlschrank stellen“

Der erste und zweite Teil des Prozesses sind in allen Sprachen klar. Der letzte Schritt ist in Low-Level-Sprachen klar, aber in High-Level-Sprachen wie JavaScript ist der letzte Schritt nicht klar.

JavaScript-Speicherzuweisung

Variableninitialisierung

Um Programmierern keine Sorgen über die Zuweisung zu machen, schließt JavaScript die Speicherzuweisung bei der Definition von Variablen ab.

Code kopieren Der Code lautet wie folgt:

var n = 123; // Speicher für numerische Variablen zuweisen
var s = "azerty"; // Zeichentyp angeben

var o = {
a: 1,
b: null
}; // Speicher für das Objekt und die darin enthaltenen Variablen zuweisen

var a = [1, null, "abra"]; // Speicher für das Array und die darin enthaltenen Variablen zuweisen (genau wie Objekte)
Funktion f(a){
gib eine 2 zurück;
} // Speicher für die Funktion (aufrufbares Objekt) reservieren

// Funktionsausdrücke können auch ein Objekt zuordnen
someElement.addEventListener('click', function(){
someElement.style.backgroundColor = 'blue';
}, false);

Speicherzuweisung per Funktionsaufruf

Einige Funktionsaufrufe führen zu einer Objektspeicherzuweisung:

Code kopieren Der Code lautet wie folgt:

var d = neues Datum();
var e = document.createElement('div'); //Ein DOM-Element zuweisen

Einige Methoden weisen neue Variablen oder neue Objekte zu:

Code kopieren Der Code lautet wie folgt:

var s = "azerty";
var s2 = s.substr(0, 3); // s2 ist eine neue Zeichenfolge
//Da die Zeichenfolge eine Invariante ist, weist JavaScript möglicherweise keinen Speicher zu, sondern speichert nur den Bereich von 0 bis 3.

var a = ["ouais ouais", "nan nan"];
var a2 = ["generation", "nan nan"];
var a3 = a.concat(a2); // Es gibt vier Elemente im neuen Array, die Array a und Array a2 verbinden.

Verwendung von Werten

Der Prozess der Verwendung von Werten ist eigentlich ein Vorgang zum Lesen und Schreiben des zugewiesenen Speichers, was bedeutet, dass Sie eine Variable oder den Attributwert eines Objekts schreiben und sogar Funktionsparameter übergeben können.

Speicher freigeben, wenn er nicht mehr benötigt wird

Die meisten Speicherverwaltungsprobleme treten in dieser Phase auf. Die schwierigste Aufgabe besteht hier darin, festzustellen, dass der zugewiesene Speicher tatsächlich nicht mehr benötigt wird. Oft muss der Entwickler ermitteln, welcher Teil des Programmspeichers nicht mehr benötigt wird, und ihn freigeben.

Der Hochspracheninterpreter bettet einen „Garbage Collector“ ein, dessen Hauptaufgabe darin besteht, die Zuweisung und Nutzung von Speicher zu verfolgen, sodass dieser automatisch freigegeben werden kann, wenn der zugewiesene Speicher nicht mehr verwendet wird. Dieser Prozess ist eine Näherung, da nicht zu entscheiden ist, ob ein bestimmtes Stück Speicher benötigt wird (kann nicht durch einen bestimmten Algorithmus gelöst werden

).

Müllabfuhr

Wie oben erwähnt, kann das Problem der automatischen Feststellung, ob ein Teil des Speichers „nicht mehr benötigt“ wird, nicht bestimmt werden. Daher können Garbage-Collection-Implementierungen allgemeine Probleme nur bedingt lösen. In diesem Abschnitt werden die Konzepte erläutert, die zum Verständnis der wichtigsten Garbage-Collection-Algorithmen und ihrer Einschränkungen erforderlich sind.

Zitat

Garbage-Collection-Algorithmen basieren hauptsächlich auf dem Konzept der Referenzen. Wenn ein Objekt im Kontext der Speicherverwaltung die Berechtigung hat, auf ein anderes Objekt zuzugreifen (implizit oder explizit), wird es als Objekt bezeichnet, das auf ein anderes Objekt verweist. Beispielsweise verfügt ein Javascript-Objekt über einen Verweis auf seinen Prototyp (einen impliziten Verweis) und einen Verweis auf seine Eigenschaften (einen expliziten Verweis).

Hier ist das Konzept „Objekt“ nicht nur ein spezielles Javascript-Objekt, sondern umfasst auch den Funktionsbereich (oder den globalen lexikalischen Bereich).

Referenzzählung Garbage Collection

Dies ist der einfachste Garbage-Collection-Algorithmus. Dieser Algorithmus vereinfacht die Definition von „ob das Objekt nicht mehr benötigt wird“ als „ob das Objekt von anderen Objekten referenziert wird“. Wenn keine Referenzen auf das Objekt vorhanden sind (null Referenzen), wird das Objekt vom Garbage-Collection-Mechanismus zurückgefordert.

Zum Beispiel

Code kopieren Der Code lautet wie folgt:

var o = {
a: {
b:2
}
};
// Zwei Objekte werden erstellt, eines wird als Eigenschaft des anderen referenziert und das andere wird der Variablen o
zugewiesen // Offensichtlich kann keines davon im Müll gesammelt werden

var o2 = o; // Die o2-Variable ist die zweite Referenz auf „dieses Objekt“
o = 1; // Jetzt wird die ursprüngliche Referenz o von „diesem Objekt“ durch o2

ersetzt

var oa = o2.a; // Referenzieren Sie die a-Eigenschaft von „diesem Objekt“
// Nun hat „dieses Objekt“ zwei Referenzen, eine ist o2 und die andere ist oa

o2 = "yo"; // Das Originalobjekt hat jetzt keine Referenzen
// Er kann im Müll gesammelt werden
// Das Objekt seines Attributs a wird jedoch immer noch von oa referenziert, sodass es noch nicht recycelt werden kann

oa = null; // Das Objekt mit dem a-Attribut hat jetzt auch Null-Referenz
// Es kann im Müll gesammelt werden

Einschränkung: Zirkelverweis

Eine Einschränkung dieses einfachen Algorithmus besteht darin, dass, wenn ein Objekt auf ein anderes verweist (und einen Zirkelverweis bildet), diese möglicherweise „nicht mehr benötigt“ werden, aber nicht recycelt werden.

Code kopieren Der Code lautet wie folgt:

Funktion f(){
var o = {};
var o2 = {};
o.a = o2; // o Referenz o2
o2.a = o; // o2 bezieht sich auf o

return „azerty“;
}

f();
// Zwei Objekte werden erstellt und verweisen aufeinander und bilden eine Schleife
// Sie verlassen den Funktionsumfang nicht, nachdem sie
aufgerufen wurden // Sie sind also nicht mehr nützlich und können recycelt werden
// Der Referenzzählalgorithmus berücksichtigt jedoch, dass sie alle mindestens eine Referenz aufeinander haben, sodass sie nicht recycelt werden

Praxisbeispiele

IE 6, 7 führt das Referenzzähl-Recycling für DOM-Objekte durch. Ein häufiges Problem für sie sind Speicherlecks:

Code kopieren Der Code lautet wie folgt:

var div = document.createElement("div");
div.onclick = function(){
doSomething();
};
// Das Div hat einen Verweis auf das Event-Handling-Attribut onclick
// Der Event-Handler hat auch einen Verweis auf das Div, auf das im Funktionsumfang
zugegriffen werden kann // Dieser Zirkelverweis führt dazu, dass beide Objekte nicht durch Garbage Collection erfasst werden

Mark-and-Clear-Algorithmus

Dieser Algorithmus vereinfacht die Definition von „ob das Objekt nicht mehr benötigt wird“ als „ob das Objekt erhalten werden kann“.

Dieser Algorithmus geht davon aus, dass ein Objekt namens root eingerichtet wird (in Javascript ist root das globale Objekt). In regelmäßigen Abständen beginnt der Garbage Collector im Stammverzeichnis, findet alle Objekte, auf die vom Stammverzeichnis aus verwiesen wird, und findet dann die Objekte, auf die diese Objekte verweisen ... Ausgehend vom Stammverzeichnis findet der Garbage Collector alle Objekte, die abgerufen werden können, und alle Objekte das kann man nicht bekommen.

Dieser Algorithmus ist besser als der vorherige, da „Objekte mit Nullreferenz“ immer nicht erhältlich sind, aber das Gegenteil ist nicht unbedingt der Fall, siehe „zyklische Referenz“.

Seit 2012 verwenden alle modernen Browser den Mark-and-Sweep-Garbage-Collection-Algorithmus. Alle Verbesserungen am JavaScript-Garbage-Collection-Algorithmus basieren auf Verbesserungen am Mark-Sweep-Algorithmus und verbessern nicht den Mark-Sweep-Algorithmus selbst und seine vereinfachte Definition, „ob ein Objekt nicht mehr benötigt wird“.

Zirkelverweise sind kein Problem mehr

Im obigen Beispiel können die beiden Objekte nach der Rückkehr des Funktionsaufrufs nicht vom globalen Objekt abgerufen werden. Daher werden sie vom Garbage Collector eingesammelt.
Im zweiten Beispiel werden das Div und seine Event-Handler, sobald sie vom Stammverzeichnis aus nicht erreichbar sind, vom Garbage Collector gesammelt.

Einschränkungen: Objekte müssen explizit nicht erreichbar sein

Obwohl dies eine Einschränkung darstellt, wird sie selten überschritten, weshalb sich in Wirklichkeit nur wenige Menschen für den Garbage-Collection-Mechanismus interessieren.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn