Einführung
Low-Level-Sprachen wie C haben Primitive wie malloc () und Free () auf niedrigem Level-Speichermanagement. Andererseits werden die Speicherprimitiven von JavaScript zugewiesen, wenn Variablen (Objekte, Zeichenfolgen usw.) erstellt und dann "automatisch" befreit werden, wenn sie nicht mehr verwendet werden. Letzteres heißt Garbage Collection. Diese "Automatik" verschleiert und gibt JavaScript (und anderen hochrangigen Sprachen) Entwicklern eine Illusion: Sie können das Gedächtnismanagement ignorieren.
Gedächtnislebenszyklus
Egal welche Programmiersprache, der Gedächtnislebenszyklus ist im Grunde der gleiche:
1. Zuordnen Sie den Speicher zu, den Sie benötigen
2. Verwenden Sie es (lesen, schreiben)
3.. PS veröffentlicht: Und "Legen Sie den Elefanten in den Kühlschrank", bedeutet dasselbe
Der erste und zweite Teile des Prozesses sind in allen Sprachen klar. Der letzte Schritt ist in Sprachen auf niedriger Ebene klar, aber in hochrangigen Sprachen wie JavaScript ist der letzte Schritt nicht klar.
Speicherzuweisung für JavaScript
Variable Initialisierung
Um Programmierer nicht mit dem Problem der Allokation zu stören, vervollständigt JavaScript beim Definieren von Variablen die Speicherzuweisung.
Die Codekopie lautet wie folgt:
var n = 123; // Speicher den numerischen Variablen Speicher zuweisen
var s = "asery"; // Zeichentyp geben
var o = {
A: 1,
B: NULL
}; // Speicher für Objekte und ihre enthaltenen Variablen Speicher zuweisen
var a = [1, null, "bra"]; // Speicher für Arrays und deren Variablen (wie Objekte) Speicher zuweisen.
Funktion f (a) {
Return a + 2;
} // Speicher für Funktionen (aufrufbare Objekte) Speicher zuweisen
// Funktionsausdrücke können auch ein Objekt zuweisen
monatelement.addeventListener ('klick', function () {
einigeLement.Style.BackgroundColor = 'Blue';
}, FALSCH);
Speicherzuweisung durch Funktionsaufrufe
Einige Funktionsaufrufe führen zum Zuordnen des Objektspeichers:
Die Codekopie 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:
Die Codekopie lautet wie folgt:
var s = "asery";
var s2 = substr (0, 3); // S2 ist eine neue Zeichenfolge
// Da String ein invarianter ist, kann JavaScript keinen Speicher zuweisen, aber nur den Bereich 0-3 gespeichert.
var a = ["ouais ouais", "nan nan"];
var a2 = ["Generation", "Nan Nan"];
var a3 = a.concat (a2); // Es gibt vier Elemente im Neuarray, die sich dem Array A und Array A2 anschließen.
Verwendung von Werten
Der Prozess der Verwendung von Werten ist tatsächlich ein Lese- und Schreibbetrieb des Zuordnungsspeichers, was bedeutet, dass eine Variable oder der Eigenschaftswert eines Objekts geschrieben werden kann oder sogar die Parameter einer Funktion übergeben werden können.
Befreit, wenn das Gedächtnis nicht mehr benötigt wird
Die meisten Probleme der Speicherverwaltung sind in dieser Phase. Die schwierigste Aufgabe hier ist, "das zugewiesene Gedächtnis wird in der Tat nicht mehr benötigt". Es erfordert häufig Entwickler, zu bestimmen, welches Gedächtnis im Programm nicht mehr benötigt wird, und frei.
Der hochrangige Sprachdolmetscher ist in einen "Müllkollektor" eingebettet. Die Hauptaufgabe besteht darin, die Zuweisung und Verwendung des Speichers so zu verfolgen, dass er automatisch freigegeben wird, wenn der zugewiesene Speicher nicht mehr verwendet wird. Dieser Vorgang ist eine Annäherung, da es unmöglich ist zu bestimmen, ob ein bestimmtes Stück Speicher bestimmt werden muss (er kann nicht von einem Algorithmus gelöst werden).
Müllrecycling
Wie oben erwähnt, ist die Frage, ob ein Speicher automatisch "nicht mehr benötigt" ist, nicht zu bestimmen. Daher kann die Umsetzung der Müllsammlung nur allgemeine Probleme mit Einschränkungen lösen. In diesem Abschnitt werden die notwendigen Konzepte erläutert, um die Hauptmüllersammlungsalgorithmen und ihre Grenzen zu verstehen.
Zitat
Die Müllsammlungsalgorithmen beruhen hauptsächlich auf das Referenzkonzept. Wenn ein Objekt in einer von Speicher verwalteten Umgebung die Erlaubnis hat, auf ein anderes Objekt (implizit oder explizit) auf ein anderes Objekt zuzugreifen, wird es als Objekt bezeichnet, das sich auf ein anderes Objekt bezieht. Beispielsweise hat ein JavaScript -Objekt einen Hinweis auf seinen Prototyp (implizite Referenz) und eine Referenz auf seine Eigenschaften (explizite Referenz).
Hier ist das Konzept von "Objekt" nicht nur spezielle JavaScript -Objekte, sondern auch Funktionsumfang (oder globaler lexikaler Bereich).
Referenzzahl Müllsammlung
Dies ist der einfachste Algorithmus zur Müllsammlung. Dieser Algorithmus vereinfacht ", ob das Objekt nicht mehr benötigt wird", da "ob das Objekt andere Objekte darauf referenziert". Wenn keine Bezugspunkte auf das Objekt (Zero Reference) verweist, wird das Objekt vom Müllmechanismus recycelt.
Zum Beispiel
Die Codekopie lautet wie folgt:
var o = {
A: {
B: 2
}
};
// Zwei Objekte werden erstellt, einer wird als Attribut des anderen bezeichnet und der andere wird der Variablen O zugewiesen
// Offensichtlich kann keiner von ihnen durch Müll gesammelt werden
var o2 = o; // Die O2 -Variable ist der zweite Verweis auf "dieses Objekt"
o = 1; // Jetzt wird die ursprüngliche Referenz O von "dieses Objekt" durch O2 ersetzt
var oa = o2.a; // Verweisen Sie auf eine Eigenschaft von "diesem Objekt"
// Jetzt gibt es zwei Verweise auf "dieses Objekt", einer ist O2 und der andere ist OA
o2 = "yo"; // Das ursprüngliche Objekt ist jetzt Null Referenz
// Er kann recycelt werden
// jedoch wird das Objekt seiner Eigenschaft A immer noch von OA verwiesen, sodass es noch nicht recycelt werden kann
oa = null; // Das Objekt mit der A -Eigenschaft wird nun auch durch Null verwiesen
// Es kann Müll gesammelt werden
Einschränkung: Recyclingreferenz
Dieser einfache Algorithmus hat eine Einschränkung, dass ein Objekt, wenn sich ein Objekt auf ein anderes bezieht (eine kreisförmige Referenz bildet), es "nicht mehr brauchen", aber nicht recycelt werden.
Die Codekopie lautet wie folgt:
Funktion f () {
var o = {};
var o2 = {};
oa = o2; // o Referenz O2
o2.a = o; // O2 Referenz o
zurück "asery";
}
F();
// Zwei Objekte werden erstellt und aufeinander verwiesen, wobei eine Schleife bildet
// Sie werden den Umfang der Funktion nicht verlassen, nachdem sie aufgerufen wurden
// sie sind also nutzlos und können recycelt werden
// Der Referenzzählalgorithmus berücksichtigt jedoch, dass sie mindestens einmal Verweise aufeinander haben, sodass sie nicht recycelt werden
Praktische Beispiele
Dh 6, 7 Recycling der Referenzzählung auf DOM -Objekten. Ein häufiges Problem für sie sind Speicherlecks:
Die Codekopie lautet wie folgt:
var div = document.createelement ("div");
div.onclick = function () {
dosometing ();
};
// Div hat eine Referenz, die auf die Event -Verarbeitungseigenschaft auf demonstriert ist
// Ereignisbearbeitung hat auch einen Verweis auf das DIV, auf das im Funktionsbereich zugegriffen werden kann
// Diese kreisförmige Referenz führt dazu, dass beide Objekte Müll gesammelt werden
Markierung von Algorithmus
Dieser Algorithmus vereinfacht ", ob das Objekt nicht mehr benötigt wird" als "ob das Objekt verfügbar ist".
In diesem Algorithmus wird ein Objekt eingestellt, das als Root bezeichnet wird (in JavaScript ist Root ein globales Objekt). Regelmäßig startet der Müllsammler an der Wurzel, findet alle aus der Wurzel verwiesenen Objekte und findet dann die von diesen Objekten verwiesenen Objekte ... Start vom Wurzel findet der Müllsammler alle Objekte, die erhalten werden können, und alle Objekte, die nicht erhalten werden können.
Dieser Algorithmus ist besser als der vorherige, da "Objekte mit null Referenzen" immer nicht verfügbar sind, aber im Gegenteil, es ist nicht unbedingt wahr, beziehen Sie sich auf "Rundreferenzen".
Seit 2012 haben alle modernen Browser den Tag-C-Clean Garbage Collection-Algorithmus verwendet. Alle Verbesserungen des Algorithmus zur Sammlung von JavaScript-Müll basieren auf Verbesserungen des Tag-Cleaning-Algorithmus, ohne den Tag-Cleaning-Algorithmus selbst und seine vereinfachte Definition darüber zu verbessern, ob das Objekt nicht mehr benötigt wird.
Kreislaufreferenzen sind kein Problem mehr
Im obigen Beispiel, nachdem der Funktionsaufruf zurückgegeben wird, können beide Objekte nicht aus dem globalen Objekt abgerufen werden. Daher werden sie vom Müllsammler recycelt.
Das zweite Beispiel auch, sobald der Div und seine Ereignisverarbeitung nicht von der Wurzel abgerufen werden können, werden sie vom Müllsammler recycelt.
Einschränkung: Objekte müssen explizit nicht verfügbar sein
Obwohl dies eine Einschränkung ist, ist es selten durchgebrochen, weshalb sich in Wirklichkeit nur wenige Menschen um den Mülleimermechanismus kümmern.