Dieser Artikel stellt hauptsächlich den Garbage-Collection-Mechanismus von js vor, der einen gewissen Referenzwert hat. Freunde in Not können sich darauf beziehen
Speicherverwaltung Es geschieht automatisch und ist für uns unsichtbar. Die von uns erstellten primitiven Typen, Objekte, Funktionen usw. belegen alle Speicher.
Was passiert, wenn sie nicht mehr benötigt werden? Wie findet und löscht die JavaScript-Engine sie?
Das Schlüsselkonzept bei der JavaScript-Speicherverwaltung ist Erreichbarkeit .
Einfach ausgedrückt sind „erreichbare“ Werte zugänglich und verfügbar und werden sicher im Speicher gespeichert.
Die folgenden Werte sind unbedingt „anfassbar“ und können aus keinem Grund gelöscht werden:
Aktuelle Funktionslokalvariablen und Parameter.
Lokale Variablen und Parameter aller Funktionen in der aktuellen Kette verschachtelter Aufrufe.
Globale Variablen.
(und andere interne Variablen)
这些值都称为 *roots*。
Ob andere Werte erreichbar sind, hängt davon ab, ob Es ist root und seine Referenzkettenreferenz.
Angenommen, es gibt ein Objekt in einer lokalen Variablen und sein Wert verweist auf ein anderes Objekt. Wenn dieses Objekt erreichbar ist, ist das Objekt, auf das es verweist, ebenfalls erreichbar.
Die JavaScript-Engine verfügt über einen Garbage-Collection-Hintergrundprozess. Es überwacht alle Objekte und löscht sie, wenn sie nicht mehr erreichbar sind.
// user has a reference to the object let user = { name: "John" };
Der Pfeil stellt eine Objektreferenz dar. Die globale Variable "user"
verweist auf das Objekt {name: "John"}
(als John bezeichnet). Johns "name"
-Attribut speichert einen primitiven Wert, daher gibt es keine andere Referenz.
Wenn Sie user
überschreiben, geht der Verweis auf John verloren:
user = null;
Jetzt ist John nicht mehr erreichbar und wird vom Garbage-Collection-Mechanismus gelöscht freier Speicher.
Wenn wir die Referenz von user
nach admin
kopieren:
// user has a reference to the object let user = { name: "John" }; *!* let admin = user; */!*
Wenn wir diesen Vorgang einmal wiederholen :
user = null;
... Auf dieses Objekt kann weiterhin über admin
zugegriffen werden, es ist also weiterhin im Speicher vorhanden. Wenn wir admin
ebenfalls auf null überschreiben, wird es gelöscht.
Dieses Beispiel ist komplizierter:
function marry(man, woman) { woman.husband = man; man.wife = woman; return { father: man, mother: woman } } let family = marry({ name: "John" }, { name: "Ann" });
marry
Die Funktion sorgt dafür, dass zwei Parameterobjekte aufeinander verweisen und gibt ein neues Objekt zurück, das beides enthält. Struktur Wie folgt:
Vorübergehend sind alle Objekte erreichbar, aber wir haben uns jetzt entschieden, zwei Referenzen zu entfernen:
delete family.father; delete family.mother.husband;
Das Löschen nur einer Referenz hat keine Auswirkungen, aber wenn beide Referenzen gleichzeitig gelöscht werden, können wir sehen, dass John von keinem Objekt mehr referenziert wird:
Auch wenn John sich immer noch auf andere bezieht, er aber nicht von anderen referenziert wird, ist John nun unantastbar und seine Existenz wird entfernt.
Nach der Speicherbereinigung:
Es können auch viele Objektblöcke vorhanden sein, die aufeinander verweisen (wie Inseln). sind außer Reichweite.
Operation für das obige Objekt:
family = null;
Die Situation im Speicher ist wie folgt:
Dieses Beispiel zeigt das „erreichbare“ The Bedeutung von Konzepten.
Obwohl John und Ann aufeinander angewiesen waren, reichte es nicht aus.
"family"
Das gesamte Objekt wurde von der Root-Verbindung abgeschnitten und nichts verweist darauf, sodass diese Insel außer Reichweite ist und nur darauf warten kann, gelöscht zu werden.
Der grundlegende Garbage-Collection-Algorithmus heißt „Mark-and-Sweep“:
Garbage Collector Holen Sie sich Root und markieren Sie es.
Dann besuchen Sie alle Zitate daraus und taggen Sie sie.
greift auf markierte Objekte zu, indem ihre Referenzen markiert werden. Alle besuchten Objekte werden aufgezeichnet und es wird in Zukunft nicht wiederholt auf dasselbe Objekt zugegriffen.
… bis nur noch unbesuchte Referenzen übrig bleiben.
Alle nicht markierten Objekte werden entfernt.
Angenommen, die Objektstruktur ist wie folgt:
Wir sehen deutlich die „Insel“ auf der rechten Seite. Verwenden Sie nun die „Mark and Clear“-Methode, um damit umzugehen.
Der erste Schritt besteht darin, die Wurzel zu markieren:
und dann ihre Referenzen zu markieren:
… …markieren Sie die Referenzen, auf die sie sich beziehen:
Objekte, auf die nicht zugegriffen wurde, gelten nun als nicht erreichbar und werden gelöscht:
So funktioniert die Müllabfuhr.
Die JavaScript-Engine hat viele Optimierungen vorgenommen, ohne die Ausführung zu beeinträchtigen, wodurch der Prozess effizienter wird:
Generationensammlung – Objekte wird in „neue Generation“ und „alte Generation“ unterteilt. Viele Gegenstände werden nach Abschluss ihrer Aufgaben bald nicht mehr benötigt und können daher häufig aufgeräumt werden. Diejenigen, die bei den Aufräumarbeiten zurückgeblieben sind, werden als Angehörige der „alten Generation“ bezeichnet.
Inkrementelle Sammlung – Wenn viele Objekte vorhanden sind, ist es schwierig, alle Objekte auf einmal zu markieren, und dieser Vorgang führt sogar zu einer erheblichen Verzögerung bei der Programmausführung. Daher wird die Engine versuchen, diesen Vorgang in mehrere Teile aufzuteilen und jeweils einen Teil auszuführen. Dies erfordert die Aufzeichnung zusätzlicher Daten, kann jedoch die Auswirkungen der Latenz auf das Benutzererlebnis wirksam reduzieren.
Leerlaufzeiterfassung – Der Garbage Collector sollte nur ausgeführt werden, wenn die CPU im Leerlauf ist, um die Auswirkungen auf die Programmausführung zu reduzieren.
Außerdem gibt es viele Optimierungen für die Garbage Collection. Ich werde hier nicht auf Details eingehen, und diese Sache wurde mit der Engine aktualisiert . Wenn es keine wirkliche Nachfrage gibt, lohnt es sich nicht, zu tief zu graben. Wenn Sie jedoch wirklich daran interessiert sind, finden Sie unten einige Erweiterungslinks.
Wichtige Punkte:
Die Speicherbereinigung erfolgt automatisch, wir können sie nicht erzwingen oder verhindern.
Erreichbare Objekte bleiben im Speicher erhalten.
Referenzen sind nicht unbedingt erreichbar (vom Stammverzeichnis aus): Objekte, die aufeinander verweisen, sind möglicherweise völlig unerreichbar.
Moderne Engines implementieren verbesserte Garbage-Collection-Algorithmen und werden im Buch „The Garbage Collection Handbook: The Art of Automatic Memory Management“ (R. Jones et al.) erwähnt.
Wenn Sie mit Low-Level-Programmierung vertraut sind, können Sie „Eine Tour durch V8: Garbage Collection“ lesen, um weitere Details zur V8-Garbage Collection zu erfahren.
Der V8-Blog veröffentlicht außerdem häufig Artikel zum Thema Speicherverwaltung. Der beste Weg, den Garbage-Collection-Algorithmus zu erlernen, besteht darin, sich zunächst mit der V8-Implementierung vertraut zu machen und den Blog von Vyacheslav Egorov (einem der V8-Ingenieure) zu lesen. Ich sage V8, weil es im Internet viele Artikel über V8 gibt. Bei anderen Engines sind viele Implementierungen ähnlich, es gibt jedoch viele Unterschiede bei den Garbage-Collection-Algorithmen.
Ein tiefgreifendes Verständnis der Engine ist bei der Optimierung auf niedriger Ebene sehr hilfreich. Nachdem Sie sich mit einer Sprache vertraut gemacht haben, ist dies eine kluge Richtung, die Sie einschlagen sollten.
Das Obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass er für das Studium aller hilfreich ist. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website.
Verwandte Empfehlungen:
So beurteilen Sie, ob die Seite über js auf dem PC oder Mobilgerät geöffnet wird
In JS detailliert Erklärung des Prototyps
Das obige ist der detaillierte Inhalt vonLassen Sie uns kurz über den Inhalt der js-Garbage Collection sprechen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!