Detaillierte Erläuterung des Garbage Collection-Mechanismus von JavaScript

Detaillierte Erläuterung des Garbage Collection-Mechanismus von JavaScript

Warum brauchen wir Garbage Collection (GC)?

  • Programme sind wie Menschen. Sie produzieren mit der Zeit Müll. Programme produzieren auch während ihrer Ausführung Müll. Wenn sich zu viel Müll ansammelt, läuft das Programm langsamer.
  • Der Speicher für Zeichenfolgen, Objekte, Arrays und andere Daten in JavaScript ist nicht festgelegt und der Speicher wird nur dann dynamisch zugewiesen, wenn er tatsächlich verwendet wird.
  • Der von diesen Daten belegte Speicher muss bei Nichtgebrauch freigegeben werden, damit er erneut verwendet werden kann. Andernfalls stürzt das Programm ab, wenn der verfügbare Speicher erschöpft ist.

Was ist Garbage Collection

Der Garbage-Collection-Mechanismus wird auch Garbage Collection oder kurz GC genannt. JavaScript verfügt über einen automatischen Speicherbereinigungsmechanismus, der mithilfe einiger Recyclingalgorithmen nicht mehr verwendete Variablen oder Eigenschaften aufspürt und den von ihnen belegten Speicherplatz in festgelegten Zeitabständen von der JS-Engine freigibt. In C/C++ müssen Programmierer die Garbage Collection manuell durchführen.

Abfallerzeugung

Wenn ein Objekt keine Variablen oder Eigenschaften hat, die darauf verweisen, können wir nie mit dem Objekt arbeiten. Dieses Objekt ist Müll. Zu viele solcher Objekte beanspruchen viel Speicherplatz und verlangsamen das Programm.

Zum Beispiel:

Bildbeschreibung hier einfügen

Hier habe ich zuerst eine Personenvariable deklariert, die auf das Objekt {name: "江流", age: 20} verweist. Dann habe ich diese Personenvariable auf ein anderes Objekt {name: "心猿", age: 5000} gerichtet. Das zuvor referenzierte Objekt wird nun zu einem nutzlosen Objekt und kann nie verwendet werden, um darauf zu arbeiten. Diese Art von Objekt ist Müll.

Wenn zu viele Müllobjekte vorhanden sind, beanspruchen sie viel Speicherplatz. Wenn sie nicht freigegeben werden, beeinträchtigt dies die Systemleistung und kann sogar zum Absturz des Programms führen. Daher ist eine Speicherbereinigung erforderlich, um diesen Teil des Speichers freizugeben.

Wir müssen und können in diesem Prozess keine Garbage Collection durchführen.

Wir müssen lediglich die Objekte, die nicht mehr verwendet werden, auf Null setzen.

Strategie zur Garbage Collection

Das Hauptkonzept der Speicherverwaltung in JavaScript ist die Erreichbarkeit. Dies bedeutet grob, dass Werte, auf die zugegriffen werden kann oder die auf irgendeine Weise verwendet werden können, im Speicher behalten werden müssen, während Werte, auf die nicht zugegriffen werden kann oder die nicht verwendet werden können, durch den Speicherbereinigungsmechanismus recycelt werden müssen.

Der Garbage Collection-Prozess wird nicht in Echtzeit ausgeführt, da JavaScript eine Single-Thread-Sprache ist. Bei jeder Ausführung der Garbage Collection wird die Anwendungslogik des Programms angehalten. Nach Abschluss der Garbage Collection wird die Anwendungslogik erneut ausgeführt. Dieses Verhalten wird als vollständige Pause bezeichnet, sodass die Garbage Collection im Allgemeinen ausgeführt wird, wenn die CPU im Leerlauf ist.

Der Schwerpunkt der Speicherbereinigung liegt auf der Suche nach sogenanntem Müll. Daher gibt es die folgenden gängigen Algorithmusstrategien. Hier sprechen wir jedoch nur über die ersten beiden:

  1. Referenzzählalgorithmus
  2. Mark-and-Sweep-Algorithmus
  3. Tag-Sortierung
  4. Generationen-Recycling

Referenzzähler-Tags

Strategisches Denken:

  • Behalten Sie im Auge, wie oft jeder Variablenwert verwendet wird
  • Wenn eine Variable deklariert und der Variablen ein Referenztypdaten zugewiesen wird, wird der Referenzzähler der Referenztypdaten als 1 markiert.
  • Wenn diese Referenztypdaten einer anderen Variablen zugewiesen werden, beträgt die Anzahl der Referenzen +1.
  • Wenn die Variable durch einen anderen Wert überschrieben wird, beträgt der Referenzzähler -1.
  • Wenn der Referenzzähler dieser Referenztypdaten 0 wird, wird die Variable nicht mehr verwendet und kann nicht aufgerufen werden. Der Garbage Collector zerstört während der Ausführung die Referenztypdaten mit einem Referenzzähler von 0 und gibt den von ihnen belegten Speicherplatz frei.

Zum Beispiel:

	sei a = {
	    Name: "Jiang Liu",
	    Alter: 20
		}; //An dieser Stelle wird der Referenzzähler des Objekts als 1 (eine Referenz) markiert
	let b = a; //An diesem Punkt wird der Referenzzähler des Objekts als 2 markiert (a, b-Referenzen)
	a = null; //An diesem Punkt wird der Referenzzähler des Objekts als 1 markiert ((b-Referenz))
	b = null; //An diesem Punkt wird der Referenzzähler des Objekts als 0 markiert (keine Variablenreferenz)
	... //Warten Sie, bis GC dieses Objekt zurückfordert

Dieser Ansatz hat jedoch ein ernstes Problem – zirkuläre Referenzen

Durch Zirkelverweise verursachte Probleme

In einer Funktion zeigt die Eigenschaft von Objekt A auf Objekt B und die Eigenschaft von Objekt B auf Objekt A. Nachdem die Funktion ausgeführt wurde, sind die Zähler der Objekte A und B nicht 0, was sich auf die normale GC auswirkt.

Beispielsweise das folgende Beispiel:

Funktionstest ()
{
    sei A = neues Objekt();
    sei B = neues Objekt();
    A.Zeiger= B;
    B.Zeiger = A;
}
prüfen();

Wenn die Eigenschaften von Objekt A und Objekt B aufeinander verweisen, beträgt ihr Referenzzähler gemäß der Referenzzählstrategie beide 2. Nachdem jedoch test () ausgeführt wurde und die Funktion ausgeführt wurde, sollten die Datenobjekte A und B im Funktionsbereich durch GC zerstört werden.

Bei mehrmaliger Ausführung kommt es zu schwerwiegenden Speicherverlusten.

Problemumgehung

Am Ende der Funktion setzen wir es auf null

// Referenzbeziehung abschneiden A = null;
B = null;

Vor- und Nachteile von Referenzzählalgorithmen

Vorteil:

  • Wenn der Referenzzähler Null ist, wird der Müll sofort gesammelt
  • Minimieren Sie Programmpausen

Mangel:

  • Objekte mit Zirkelreferenz können nicht zurückgefordert werden
  • Hohe Platzkosten

Mark-and-Sweep-Algorithmus

Kernidee

Der Vorgang wird in zwei Phasen durchgeführt: Markieren und Räumen.

Ungefährer Ablauf:

  • Der Garbage Collector fügt während seiner Ausführung allen Variablen im Speicher eine Markierung hinzu. Unter der Annahme, dass alle Objekte im Speicher Müll sind, werden alle mit 0 markiert.
  • Beginnen Sie dann mit der Durchquerung von jedem Stammobjekt und ändern Sie die Knoten, die kein Müll sind, in 1
  • Bereinigen Sie den gesamten mit 0 markierten Müll, zerstören Sie ihn und geben Sie den Speicherplatz frei, den er belegt
  • Ändern Sie abschließend die Markierung aller Objekte im Speicher auf 0 und warten Sie auf die nächste Runde der Garbage Collection.

Bildbeschreibung hier einfügen

Vor- und Nachteile des Mark-Sweep-Algorithmus

Vorteil:

  • Die Implementierung ist einfach. Die Markierungssituationen sind nichts anderes als zwei Situationen: treffen oder nicht treffen. Sie können binär (0 und 1) markiert werden.
  • Möglichkeit zum Recycling von Objekten mit zirkulären Referenzen
  • Es handelt sich um den am häufigsten verwendeten Algorithmus in der V8-Engine.

Mangel:

Nach der Garbage Collection bleiben die Speicherorte der verbleibenden Objekte unverändert, was zu diskontinuierlichem freiem Speicherplatz führt. Dies führt zu einer Speicherfragmentierung und da der verbleibende Speicherplatz kein ganzer Block ist, wird die Speicherzuweisung zum Problem.

Mark-Sweep-Algorithmus

Der Mark-Compact-Algorithmus kann dieses Problem effektiv lösen. Nach der Markierung verschiebt der Mark-Compact-Algorithmus die Objekte, die nicht bereinigt werden müssen, an ein Ende des Speichers und bereinigt schließlich den Speicher an der Grenze.

Bildbeschreibung hier einfügen

Garbage Collection im V8-Motor

  • Die Garbage Collection des V8-Motors verwendet Mark-Sweep- und Generational-Collection-Methoden
  • Unterteilt in neue Generation und alte Generation

Verwenden Sie für unterschiedliche Objekte unterschiedliche Algorithmen:

(1) Neue Generation: Objekte haben eine kürzere Überlebenszeit. Neue Objekte oder Objekte, für die nur einmal die Speicherbereinigung durchgeführt wurde.

(2) Alte Generation: Objekte überleben länger. Ein Objekt, das einer oder mehreren Garbage Collections unterzogen wurde.

Recycling von Objekten der neuen Generation

Die Objekte der neuen Generation werden hauptsächlich durch die Verwendung des Kopieralgorithmus (Scavenge-Algorithmus) und des Mark-Sweep-Algorithmus recycelt. Die spezifische Implementierung des Scavenge-Algorithmus verwendet hauptsächlich den Cheney-Algorithmus.

Objektförderungsmechanismus

Die neue Generation, die eine GC-Runde überlebt, muss gefördert werden.

Recycling von Gegenständen der alten Generation

Die Mark-Sweep-, Mark-Compact- und inkrementellen Mark-Algorithmen werden hauptsächlich zum Recycling von Objekten der alten Generation verwendet. Der Mark-Sweep-Algorithmus wird hauptsächlich verwendet, und der Mark-Compact-Algorithmus wird nur verwendet, wenn die Speicherzuweisung nicht ausreicht.

  • Verwenden Sie zunächst Mark-Sweep, um die Wiederherstellung des Garbage Space abzuschließen.
  • Verwenden Sie Markierungen, um den Platz zu optimieren.
  • Verwenden Sie inkrementelle Markierungen, um die Effizienz zu optimieren.

Referenzdokumente:

JS-Speicherbereinigungsmechanismus

JavaScript GC-Speicherbereinigungsmechanismus

Zusammenfassen

Dieser Artikel endet hier. Ich hoffe, er kann Ihnen helfen. Ich hoffe auch, dass Sie mehr Inhalt auf 123WORDPRESS.COM lesen können!

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung von Beispielen für JS-Closure- und Garbage-Collection-Mechanismen
  • Detailliertes Beispiel für Garbage Collection und Speicherlecks in JavaScript
  • Sprechen Sie über den Garbage Collection-Mechanismus in JavaScript
  • JavaScript-Garbage-Collection-Mechanismus und Speicherverwaltung
  • Zusammenfassung der Wissenspunkte zur Garbage Collection der neuen Generation in js

<<:  Verschiedene Methoden zum Aufrufen von js in einem werden herausgestellt und zur Verwendung empfohlen.

>>:  Häufige Browserkompatibilitätsprobleme (Zusammenfassung)

Artikel empfehlen

Einführung und detaillierte Verwendung von React Fragment

Inhaltsverzeichnis Vorwort Motivation für Fragmen...

Was die Website am meisten braucht, ist eine Verbesserung der Erfahrung der Zielgruppe

„Der große Fluss fließt nach Osten, die Wellen sp...

MySQL-Primärschlüssel-Benennungsstrategie im Zusammenhang

Als ich kürzlich die Details der Datenlebenszyklu...

Implementierungscode für den MySQL-Protokolltrigger

SQL-Anweisung DROP-TRIGGER WENN EXISTIERT sys_men...

So drücken Sie relative Pfade in Linux aus

Wenn Ihr aktueller Pfad beispielsweise /var/log i...

Lösung für EF (Entity Framework)-Einfüge- oder Aktualisierungsfehler

Fehlermeldung: Die Store-Update-, Insert- oder De...

Auswahl der Groß-/Kleinschreibung von MySQL-Tabellennamen

Inhaltsverzeichnis 1. Parameter, die die Groß-/Kl...

Verwenden von Zabbix zum Überwachen des Ogg-Prozesses (Linux-Plattform)

Der Ogg-Prozess einer vor einiger Zeit erstellten...

Beispiel für die Implementierung einer virtuellen Liste im WeChat Mini-Programm

Inhaltsverzeichnis Vorwort analysieren Erste Rend...

Detaillierte Erklärung der MySQL-Gruppierung durch Optimierung

Inhaltsverzeichnis Standardausführungsprozess Opt...

Die Fallstricke bei der Bereitstellung von Angular-Projekten in Nginx

Wenn man online nach Methoden sucht, um Angular -...