Javascript-Kolumne stellt allen den Garbage-Collection-Mechanismus, Speicherlecks und Schließungsinhalte vor.
Vorn geschrieben: Dies ist eine Serie, die ich in der Javascript-Kolumne schreiben werde, obwohl ich Frameworks für die Arbeit, für Interviews und den technischen Fortschritt verwende Grundlegende JS-Kenntnisse sind das Tüpfelchen auf dem i, und es ist auch ein Stück Wissen, das erlernt werden muss. Obwohl Menschen, die Autos fahren, nicht viel über Autos wissen müssen, müssen sie nur die allgemeinen Funktionen von Autos beherrschen. Aber wer sich mit Autos auskennt, kann auch besser fahren. Natürlich geht es in einem Artikel nicht nur um einen einzelnen Wissenspunkt. Im Allgemeinen werden verwandte Wissenspunkte in Reihe geschaltet. Während Sie Ihr eigenes Lernen aufzeichnen, teilen Sie Ihr eigenes Lernen und ermutigen sich gegenseitig. Wenn Sie können, geben Sie mir bitte auch ein „Gefällt mir“, Ihre „Gefällt mir“-Angaben werden mich auch dazu bringen, härter an der Aktualisierung zu arbeiten!
Übersicht
Essenszeit: 6-12 Minuten
Schwierigkeit:
Einfach, nicht rennen, warten, bis Sie mit dem Lesen fertig sind
MüllsammelmechanismusDer vorherige Blog erklärt hauptsächlich die Zuordnung und Verwendung von Speicher (Stapelspeicher und Heap-Speicher, tiefe Kopie und flache Kopie). Nach der Verwendung müssen Sie natürlich den nicht verwendeten Speicher zurückgeben, genau wie das Löschen der nicht verwendeten Software auf dem Mobiltelefon aus dem Hintergrund, was die Laufgeschwindigkeit des Telefons verbessern kann Das gleiche gilt für JS.
function changeName(){ var obj1={}; var obj2={};
obj1.target=obj2;
obj2.target=obj1;
obj1.age=15; console.log(obj1.target); console.log(obj2.target);
}
changeName();复制代码
在函数执行完毕的时候, obj1 和 obj2 还是活的好好地,因为 obj1.target 和 obj2.targetVon Zeit zu Zeit „patrouilliert“ der „Garbage Collector“ von JS durch Variablen, genau wie Sicherheitskräfte im Park patrouillieren, und lässt irrelevante Personen schnell gehen. Wenn eine Variable nicht mehr benötigt wird, wird der von der Variablen belegte Speicherplatz freigegeben. Dieser Vorgang wird als bezeichnet. Der Garbage-Collection-Algorithmus von JS ist in zwei Typen unterteilt: Referenzzählung und Markierungslöschung
Referenzzählung
Die Referenzzählung ist der rudimentärste Garbage-Collection-Algorithmus und wurde von modernen Browsern eliminiert. Bevor Sie die Referenzzählmethode erlernen, müssen Sie zunächst über ein bestimmtes Konzept von „Referenz“ verfügen. Sie können es sich als eine Beschreibung der Speicheradresse vorstellen, auf die die aktuelle Variable zeigt. Es ähnelt in gewisser Weise dem Konzept des Speicherzeigens Schauen wir uns zunächst eine Codezeile an:
function changeName(){ var obj1={}; var obj2={};
obj1.target=obj2;
obj2.target=obj1;
obj1.age=15; console.log(obj1.target); console.log(obj2.target);
}
changeName();复制代码
Nach dem Login kopieren
Nach dem Login kopieren
Wenn wir obj einen Wert zuweisen, erstellen wir tatsächlich eine Referenz, die auf die Variable zeigt, mit einem Referenzzähler von 1 , Unter dem Mechanismus der Referenzzählung entspricht jeder Wert im Speicher einer ReferenzanzahlUnd wenn wir objnull zuweisen, wird diese Variable zu a Stück nutzloser Speicher, dann beträgt der Referenzzähler von obj zu diesem Zeitpunkt
0
und wird vom Garbage Collector recycelt, dh der von obj belegte Speicherplatz wird freigegeben
Wir wissen, dass der Lebenszyklus eines Funktionsumfangs sehr kurz ist. Nach der Ausführung der Funktion sind die darin enthaltenen Variablen im Grunde genommen nutzlose Variablen Wenn Sie den ursprünglichen Speicher nicht loslassen, führt dies leicht zu einem
Speicherverlust
. Schauen wir uns zunächst einen Codeabschnitt und die laufenden Ergebnisse an:
function f1(){ var n=999;
nAdd=function(){n+=1} function f2(){ console.log(n);
} return f2;
} var result=f1(); //等同于return f2();
result(); // 999
nAdd();
result(); // 1000
nAdd();
result(); // 1000复制代码
Nach dem Login kopieren
Nach dem Login kopieren
Wir können sehen, dass < code>obj1.target und obj2.target aufeinander verweisen, denn wenn obj1.age</code > geändert wird, sind auch <code>obj1.target.age und obj2.target.age gleichzeitig betroffen, und die Referenzanzahlen, auf die sie verweisen, sind konsistent, wenn die Funktion ausgeführt wird Wenn die Ausführung abgeschlossen ist, sind obj1 und obj2 noch am Leben, da die Referenzanzahl von obj1.target und obj2.target</ Code> ist nach der Ausführung immer noch </strong>1</p> Offensichtlich wurde die Funktion ausgeführt, aber wenn es zu viele solcher Funktionen gibt, sind </li>Speicherlecks<li>unvermeidlich<p><strong></strong></p>Markierungs- und Löschmethode🎜🎜 Die Nachteile der oben genannten Referenzzählmethode liegen auf der Hand. Dann gibt es bei der Markierungs- und Löschmethode, über die wir jetzt sprechen, kein solches Problem. Da der verwendete Beurteilungsstandard darin besteht, festzustellen, ob das Objekt 🎜 erreichbar ist 🎜, ist er hauptsächlich in zwei Phasen unterteilt, 🎜 Markierungsphase 🎜 und 🎜 Löschphase 🎜: 🎜🎜🎜🎜 Markierungsphase 🎜🎜Der Müllsammler beginnt mit dem Root-Objekt (Fensterobjekt) und scannen Sie alle erreichbaren Objekte. Dies ist die sogenannte 🎜erreichbare🎜🎜🎜🎜🎜Freigabephase
Beim Scannen werden Objekte, die vom Stammobjekt nicht erreicht werden können (🎜unerreichbar🎜), als unnötig betrachtet und als Müll gelöscht</li></ul><p>现在再来看下上面的代码</p><div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>function changeName(){ var obj1={}; var obj2={};
obj1.target=obj2;
obj2.target=obj1;
obj1.age=15; console.log(obj1.target); console.log(obj2.target);
}
changeName();复制代码</pre><div class="contentsignin">Nach dem Login kopieren</div></div><div class="contentsignin">Nach dem Login kopieren</div></div><p>在函数执行完毕之后,函数的声明周期结束,那么现在,从 <code>Window对象 出发, obj1 和 obj2 都会被垃圾收集器标记为不可抵达,这样子的情况下,互相引用的情况也会迎刃而解。
Das obige ist der detaillierte Inhalt vonVerstehen Sie den Garbage-Collection-Mechanismus, Speicherlecks und Schließungen der JS-Serie (3) mit einem Blatt Papier. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!
Erklärung dieser Website
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
C++-Lambda-Ausdrücke unterstützen Abschlüsse, die Funktionsbereichsvariablen speichern und sie für Funktionen zugänglich machen. Die Syntax lautet [capture-list](parameters)->return-type{function-body}. Capture-Liste definiert die zu erfassenden Variablen. Sie können [=] verwenden, um alle lokalen Variablen nach Wert zu erfassen, [&], um alle lokalen Variablen nach Referenz zu erfassen, oder [Variable1, Variable2,...], um bestimmte Variablen zu erfassen. Lambda-Ausdrücke können nur auf erfasste Variablen zugreifen, den ursprünglichen Wert jedoch nicht ändern.
Ein Abschluss ist eine verschachtelte Funktion, die auf Variablen im Bereich der äußeren Funktion zugreifen kann. Zu ihren Vorteilen gehören Datenkapselung, Zustandserhaltung und Flexibilität. Zu den Nachteilen gehören der Speicherverbrauch, die Auswirkungen auf die Leistung und die Komplexität des Debuggens. Darüber hinaus können Abschlüsse anonyme Funktionen erstellen und diese als Rückrufe oder Argumente an andere Funktionen übergeben.
Speicherlecks können dazu führen, dass der Speicher des Go-Programms kontinuierlich zunimmt, indem: Ressourcen geschlossen werden, die nicht mehr verwendet werden, wie z. B. Dateien, Netzwerkverbindungen und Datenbankverbindungen. Verwenden Sie schwache Referenzen, um Speicherlecks zu verhindern, und zielen Sie auf Objekte für die Garbage Collection ab, wenn sie nicht mehr stark referenziert sind. Bei Verwendung von Go-Coroutine wird der Speicher des Coroutine-Stapels beim Beenden automatisch freigegeben, um Speicherverluste zu vermeiden.
Valgrind erkennt Speicherlecks und Fehler, indem es die Speicherzuweisung und -freigabe simuliert. Um es zu verwenden, befolgen Sie diese Schritte: Installieren Sie Valgrind: Laden Sie die Version für Ihr Betriebssystem von der offiziellen Website herunter und installieren Sie sie. Kompilieren Sie das Programm: Kompilieren Sie das Programm mit Valgrind-Flags (z. B. gcc-g-omyprogrammyprogram.c-lstdc++). Analysieren Sie das Programm: Verwenden Sie den Befehl valgrind--leak-check=fullmyprogram, um das kompilierte Programm zu analysieren. Überprüfen Sie die Ausgabe: Valgrind generiert nach der Programmausführung einen Bericht, der Speicherlecks und Fehlermeldungen anzeigt.
Ein Speicherverlust in C++ bedeutet, dass das Programm Speicher zuweist, aber vergisst, ihn freizugeben, wodurch der Speicher nicht wiederverwendet wird. Zu den Debugging-Techniken gehören die Verwendung von Debuggern (wie Valgrind, GDB), das Einfügen von Assertionen und die Verwendung von Bibliotheken zur Erkennung von Speicherlecks (wie Boost.LeakDetector, MemorySanitizer). Es demonstriert die Verwendung von Valgrind zur Erkennung von Speicherlecks anhand praktischer Fälle und schlägt Best Practices zur Vermeidung von Speicherlecks vor, darunter: Immer zugewiesenen Speicher freigeben, intelligente Zeiger verwenden, Speicherverwaltungsbibliotheken verwenden und regelmäßige Speicherprüfungen durchführen.
Abschlüsse in Java ermöglichen es inneren Funktionen, auf äußere Bereichsvariablen zuzugreifen, selbst wenn die äußere Funktion beendet wurde. Durch anonyme innere Klassen implementiert, enthält die innere Klasse einen Verweis auf die äußere Klasse und hält die äußeren Variablen aktiv. Schließungen erhöhen die Codeflexibilität, Sie müssen sich jedoch des Risikos von Speicherverlusten bewusst sein, da Verweise auf externe Variablen durch anonyme innere Klassen diese Variablen am Leben halten.
Funktionsabschlüsse der Go-Sprache spielen beim Unit-Testen eine wichtige Rolle: Werte erfassen: Abschlüsse können auf Variablen im äußeren Bereich zugreifen, sodass Testparameter erfasst und in verschachtelten Funktionen wiederverwendet werden können. Vereinfachen Sie den Testcode: Durch die Erfassung von Werten vereinfachen Abschlüsse den Testcode, indem sie die Notwendigkeit beseitigen, Parameter für jede Schleife wiederholt festzulegen. Verbessern Sie die Lesbarkeit: Verwenden Sie Abschlüsse, um die Testlogik zu organisieren und so den Testcode klarer und leichter lesbar zu machen.
Anonyme Funktionen sind prägnant und anonym, weisen jedoch eine schlechte Lesbarkeit und Schwierigkeiten beim Debuggen auf; Schließungen können Daten kapseln und den Status verwalten, können jedoch zu Speicherverbrauch und Zirkelverweisen führen. Praktischer Fall: Anonyme Funktionen können für die einfache numerische Verarbeitung verwendet werden, und Abschlüsse können die Zustandsverwaltung implementieren.