JS verfügt über einen vollständigen Speicherverarbeitungsmechanismus, sodass wir der Implementierung vorher keine besondere Aufmerksamkeit schenken mussten. Wenn die Seite nicht schnell ist, aktualisieren Sie sie einfach und es ist in Ordnung; wenn der Browser hängen bleibt, starten Sie ihn neu und es ist in Ordnung. Mit der Beliebtheit von SPA und mobilen Apps sowie der möglichen Implementierung von PWA in der Zukunft könnte der JS-Speicher jedoch zu einem neuen Speicherengpass werden.
Wenn wir beschließen, einen Teil des Speichers nicht mehr zu verwenden, kann GC aufgrund einer falschen Codierung nicht durchgeführt werden (Gabbage Collection) Das korrekte Recycling dieser Erinnerungen ist ein Speicherleck.
Der von einem Objekt belegte Speicher wird in direkt belegten Speicher (Shallow Size) und insgesamt belegten Speicher (Retained Size) unterteilt.
Belegt Speicher direkt : Der vom Objekt selbst belegte Speicher. Ein typisches JavaScript-Objekt verfügt über reservierten Speicher, der zum Beschreiben des Objekts und zum Speichern seiner direkten Werte verwendet wird. Im Allgemeinen belegen nur Arrays und Zeichenfolgen erheblich den Speicher (flache Größe). Aber Strings und Arrays speichern oft den Hauptdatenteil im Renderer-Speicher und legen nur ein kleines Wrapper-Objekt im JavaScript-Objektstapel offen.
Gesamtspeicher belegt: Direkt belegter Speicher und Speicher, der von abhängigen Objekten belegt ist, auf die durch diese Referenz verwiesen wird.
Zuweisungen und neue Vorgänge erfordern eine Speichernutzung.
Der Garbage Collection (GC)-Algorithmus von Chrome V8 basiert auf der Generational Collection. Der Speicher ist in zwei Typen unterteilt, die als „ Für die junge Generation (YG) und die alte Generation (OG).
Die sogenannten Jung und Alt werden nach der Zeit eingeteilt, die sie in Anspruch nehmen. Die Speicherzuweisung und -wiederverwendung erfolgt in YG schnell und häufig und ist im Allgemeinen nur für kurze Zeit vorhanden, daher wird sie als „Jung“ bezeichnet, während sie in OG langsam ist und selten auftritt und daher als „Alt“ bezeichnet wird.
Weil in V8 der GC-Prozess von YG das Programm blockiert, der GC von OG jedoch nicht. Daher sind Entwickler normalerweise mehr auf die Details von YG bedacht.
YG ist in zwei Raumteile unterteilt, die jeweils Von und Bis genannt werden. Der gesamte Speicher wird aus dem To-Bereich zugewiesen. Wenn To voll ist, wird GC ausgelöst.
Irgendwann hat To den Speicher in A, B und C zugewiesen. Derzeit ist noch ein kleiner Teil des Speichers übrig, der nicht zugewiesen wurde, während der gesamte Speicher von From vorhanden ist frei.
Zu diesem Zeitpunkt muss ein Programm Speicher für D zuweisen, aber die von D benötigte Speichergröße übersteigt die nicht zugewiesene Größe Zum Speicher, wie unten gezeigt. Zu diesem Zeitpunkt wird GC ausgelöst und die Seite wird nicht mehr ausgeführt.
Dann werden From und To vertauscht, das heißt, der ursprüngliche To-Bereich wird als From und From als To markiert. Und wenn die Live-Variablenwerte (z. B. B) markiert sind und der „Müll“ (z. B. AC) nicht markiert ist, werden sie gelöscht.
Das Live-B wird in den To-Bereich kopiert und der „Müll“-AC wird recycelt. Gleichzeitig wird D dem zugeordnet Im Weltraum sieht es schließlich wie in der Abbildung unten aus. Die Verteilung von
An diesem Punkt ist der gesamte GC Der Vorgang ist abgeschlossen und die Seite wird während dieses Vorgangs nicht mehr ausgeführt. Daher sollte er so schnell wie möglich erfolgen. Wenn der Wert in YG über einen längeren Zeitraum bestehen bleibt, wird er auf OG verschoben. Wenn der Speicherplatz in OG voll ist, wird der GC in OG ausgelöst.
Jede Zuweisung reduziert den verfügbaren Speicherplatz von To und das Programm ist näher an GC
YGs GC blockiert das Programm, daher sollte die GC-Zeit nicht zu lang sein, weniger als 10 ms, da GC nicht zu häufig auftreten sollte
Nachdem ein bestimmter Wert zu Müll geworden ist, wird der Speicher nicht sofort freigegeben. Der belegte Speicher wird nur während der GC wiederverwendet.
2.2 Der Inhalt stammt aus der Referenz
GC Root ist der Stammknoten des Speichers. Es ist ein Fenster im Browser und ein globales Objekt in NodeJS.
Durchlaufen Sie den Graphen ausgehend von der GC-Wurzel. Alle erreichbaren Knoten werden als Live-Knoten bezeichnet GC Root, dann der Knoten Es heißt „Müll“ und wird recycelt, wie im grauen Knoten in der Abbildung dargestellt.
Das Recycling von Root-Knoten unterliegt nicht der Kontrolle des Benutzers.
Da der Pfad zum Wurzelknoten nicht vollständig unterbrochen ist, wird der automatische GC diesen Teil des Speichers nicht zurückgewinnen, was zu einem Speicherverlust führt.
Die spezifischen Gründe sind:
Gegenseitige Bezüge zwischen Objekten
<span style="font-size: 14px;">var a, b;<br>a.reference = b;<br>b.reference = a;<br></span>
Falsche Verwendung der globalen Variablen
<span style="font-size: 14px;">a = "1234567";<br>相当于<br>window.a = "1234567";<br></span>
Wenn die DOM-Element wird gelöscht oder gelöscht, das gebundene Ereignis wird nicht gelöscht
<span style="font-size: 14px;"><p id="myp"><br> <input type="button" value="Click me" id="myBtn"><br></p><br><br><script type="text/javascript"><br> var btn = document.getElementById('myBtn');<br> btn.onclick = function () {<br> document.getElementById('myp').innerHTML = 'Processing...';<br> /* 清除事件绑定 */<br> // btn.onclick = null;<br> };<br></script><br></span>
Abschlussreferenz
<span style="font-size: 14px;">function bindEvent() {<br> var obj = document.getElementById('xxx');<br><br> obj.onclick = function () {<br> /** 空函数*/<br> };<br><br> /** delete this reference */<br> // obj = null;<br>}<br></span>
Wenn das DOM-Element gelöscht oder gelöscht wird, gibt es JS-Verweise auf das untergeordnete Element, was dazu führt, dass alle übergeordneten Elemente des untergeordneten Elements nicht gelöscht werden
<span style="font-size: 14px;">// b是a的子dom节点, a是body的子节点<br>var aElement = document.getElementById("a");<br>var bElement = document.getElementById("b");<br>document.body.removeChild(aElement);<br>// aElement = null;<br>// bElement = null;<br></span>
erscheint häufiger in NodeJS, zum Beispiel:
Unkontrollierte Schleife
<span style="font-size: 14px;">while(1) {<br> // do sth<br>}<br></span>
Übergroßes Array
<span style="font-size: 14px;">var arr = [];<br>for (var i=0; i< 100000000000; i++) {<br> var a = {<br> 'desc': 'an object'<br> }<br> arr.push(a);<br>}<br></span>
Detaillierte Einführung in die Speicherverwaltung unter Linux
php Detaillierte Erklärung des Garbage-Collection-Mechanismus der Speicherverwaltung (Bild)
So vermeiden Sie JavaScript-Speicherlecks und Speicherverwaltungstechniken
Das obige ist der detaillierte Inhalt vonBeispiele für die JS-Speicherverwaltung erklärt. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!