Inhaltsverzeichnis
引用计数法
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: " >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:

  • 内存泄漏
    闭包
    定义与特性
    系列目录
    一张纸懂JS系列(1)之编译原理,作用域,作用域链,变量提升,暂时性死区" >一张纸懂JS系列(1)之编译原理,作用域,作用域链,变量提升,暂时性死区
    一张纸搞懂JS系列(2)之JS内存生命周期,栈内存与堆内存,深浅拷贝" >一张纸搞懂JS系列(2)之JS内存生命周期,栈内存与堆内存,深浅拷贝
    一张纸搞懂JS系列(3)之垃圾回收机制,内存泄漏,闭包
    Heim Web-Frontend js-Tutorial Verstehen Sie den Garbage-Collection-Mechanismus, Speicherlecks und Schließungen der JS-Serie (3) mit einem Blatt Papier

    Verstehen Sie den Garbage-Collection-Mechanismus, Speicherlecks und Schließungen der JS-Serie (3) mit einem Blatt Papier

    Sep 30, 2020 pm 04:38 PM
    内存泄漏 垃圾回收机制 闭包

    Die

    Javascript-Kolumne stellt allen den Garbage-Collection-Mechanismus, Speicherlecks und Schließungsinhalte vor.

    Verstehen Sie den Garbage-Collection-Mechanismus, Speicherlecks und Schließungen der JS-Serie (3) mit einem Blatt Papier

    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üllsammelmechanismus

    Der 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.

    JS 也是一样的。

    每隔一段时间, JS垃圾收集器都会对变量进行“巡逻”,就和保安巡逻园区一样,让不相干的人赶紧走。当一个变量不被需要了以后,它就会把这个变量所占用的内存空间所释放,这个过程就叫做垃圾回收

    JS 的垃圾回收算法分为两种,引用计数法和标记清除法

    • 引用计数法

      引用计数法是最初级的垃圾回收算法,已经被现代浏览器所淘汰了。在学习引用计数法之前,需要首先对引用有一定的概念,你可以认为它就是对当前变量所指向的那块内存地址的描述,有点类似于JS引用数据类型的内存指向的概念,先来看一行代码:

      var obj={name:'jack'};复制代码
      Nach dem Login kopieren

      当我们在给 obj 赋值的同时,其实就创建了一个指向该变量的引用,引用计数为1,在引用计数法的机制下,内存中的每一个值都会对应一个引用计数

      而当我们给 obj 赋值为 null时,这个变量就变成了一块没用的内存,那么此时, obj 的引用计数将会变成 0,它将会被垃圾收集器所回收,也就是 obj 所占用的内存空间将会被释放

      我们知道,函数作用域的生命周期是很短暂的,在函数执行完毕之后,里面的变量基本是没用的变量了,不清除的后果就是该内存垃圾没有被释放,依然霸占着原有的内存不松手,就会容易引发内存泄漏,先来看一段代码以及运行结果:

      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
      Verstehen Sie den Garbage-Collection-Mechanismus, Speicherlecks und Schließungen der JS-Serie (3) mit einem Blatt Papier
      我们可以看到, obj1.targetobj2.target 存在互相引用的情况,因为在改变 obj1.age 的同时,obj1.target.ageobj2.target.age 也同时都被影响到了,它们所指向的引用计数是一致的

      在函数执行完毕的时候, obj1obj2 还是活的好好地,因为 obj1.targetobj2.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 obj null 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
        Verstehen Sie den Garbage-Collection-Mechanismus, Speicherlecks und Schließungen der JS-Serie (3) mit einem Blatt Papier
        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对象 出发, obj1obj2 都会被垃圾收集器标记为不可抵达,这样子的情况下,互相引用的情况也会迎刃而解。

      内存泄漏

      该释放的内存垃圾没有被释放,依然霸占着原有的内存不松手,造成系统内存的浪费,导致性能恶化,系统崩溃等严重后果,这就是所谓的内存泄漏

      闭包

      • 定义与特性

        闭包是指有权访问另一个函数作用域中的变量的函数。至于为什么有权访问,主要是因为作用域嵌套作用域,也就是所谓的作用域链,关于作用域链不清楚的可以看我的第一篇博客一文搞懂JS系列(一)之编译原理,作用域,作用域链,变量提升,暂时性死区,就是因为作用域链的存在,所以内部函数才可以访问外部函数中定义的变量 ,作用域链是向外不向内的,探出头去,向外查找,而不是看着锅里,所以外部函数是无法访问内部函数定义的变量的。并且,还有一个特性就是将闭包内的变量始终保持在内存中。

        前面的作用域向外不向内,这里就不再做过多解释了,我们主要来看我后面说的特性,那就是闭包内的变量始终保存在内存中

        来看一下阮一峰教程当中的一个例子

         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

        从输出结果就可以看得出来,这个变量 n 就一直保存在内存中,那么,为什么会这样子呢,我们现在就来逐步地分析代码

        ① 首先 f1() 作为 f2() 的父函数,根据作用域链的规则, nAdd() 方法以及 f2() 方法中可以正常访问到 n 的值

        f2() 被赋予了一个全局变量,可能这里大家就会开始产生疑惑了,这个 f2() 不是好好地定义在了 f1() 函数中吗,这不是扯淡吗,那么,先看下面的这句 var result=f1(); ,这个 result 很明显是被赋予了一个全局变量,这应该是没有任何争议的,那么,接着来看这个 f1() ,可以看到最后,是一句 return f2; ,看到这里,想必大家也已经想明白了,这个 f2() 被赋予了一个全局变量

        ③ 已经明白了上面的这一点以后,根据上面垃圾回收机制所提及到的标记清除法,这个 f2() 始终是可以被根对象 Window 访问到的,所以 f2 将始终存在于内存之中,而 f2 是依赖于 f1 ,因此 f1 也将始终存在于内存当中,那么, n 的值也就自然始终存在于内存当中啦

        ④ 还有一点需要注意的就是为什么我们可以直接执行 nAdd() ,这是因为在 nAdd() 的前面没有使用 var ,因此 nAdd() 是一个全局函数而不是局部函数

        所以,闭包的变量会常驻内存,滥用闭包容易造成内存泄漏,特别是在 IE 浏览器下,2020年了,应该没人使用 IE 了吧(小声bb),解决办法就是在退出函数之前,将不使用的局部变量全部删除,这也是上面讲了垃圾回收机制 => 内存泄漏,再讲到闭包的原因,我会尽量将有关联性的知识点一起讲了,也方便大家学习和加深印象。

      系列目录

      相关免费学习推荐:javascript(视频)

      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

    Heiße KI -Werkzeuge

    Undresser.AI Undress

    Undresser.AI Undress

    KI-gestützte App zum Erstellen realistischer Aktfotos

    AI Clothes Remover

    AI Clothes Remover

    Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

    Undress AI Tool

    Undress AI Tool

    Ausziehbilder kostenlos

    Clothoff.io

    Clothoff.io

    KI-Kleiderentferner

    AI Hentai Generator

    AI Hentai Generator

    Erstellen Sie kostenlos Ai Hentai.

    Heißer Artikel

    R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Beste grafische Einstellungen
    4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
    1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O. Chat -Befehle und wie man sie benutzt
    1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

    Heiße Werkzeuge

    Notepad++7.3.1

    Notepad++7.3.1

    Einfach zu bedienender und kostenloser Code-Editor

    SublimeText3 chinesische Version

    SublimeText3 chinesische Version

    Chinesische Version, sehr einfach zu bedienen

    Senden Sie Studio 13.0.1

    Senden Sie Studio 13.0.1

    Leistungsstarke integrierte PHP-Entwicklungsumgebung

    Dreamweaver CS6

    Dreamweaver CS6

    Visuelle Webentwicklungstools

    SublimeText3 Mac-Version

    SublimeText3 Mac-Version

    Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

    Wie implementiert man einen Abschluss im C++-Lambda-Ausdruck? Wie implementiert man einen Abschluss im C++-Lambda-Ausdruck? Jun 01, 2024 pm 05:50 PM

    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.

    Was sind die Vor- und Nachteile von Abschlüssen in C++-Funktionen? Was sind die Vor- und Nachteile von Abschlüssen in C++-Funktionen? Apr 25, 2024 pm 01:33 PM

    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.

    Wie vermeidet man Speicherlecks bei der technischen Leistungsoptimierung von Golang? Wie vermeidet man Speicherlecks bei der technischen Leistungsoptimierung von Golang? Jun 04, 2024 pm 12:27 PM

    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.

    Wie erkennt man Speicherlecks mit Valgrind? Wie erkennt man Speicherlecks mit Valgrind? Jun 05, 2024 am 11:53 AM

    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.

    Debugging-Techniken für Speicherlecks in C++ Debugging-Techniken für Speicherlecks in C++ Jun 05, 2024 pm 10:19 PM

    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.

    Wie werden Schließungen in Java implementiert? Wie werden Schließungen in Java implementiert? May 03, 2024 pm 12:48 PM

    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.

    Die Rolle des Golang-Funktionsschlusses beim Testen Die Rolle des Golang-Funktionsschlusses beim Testen Apr 24, 2024 am 08:54 AM

    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.

    Zusammenfassung der Vor- und Nachteile anonymer Golang-Funktionen und -Verschlüsse Zusammenfassung der Vor- und Nachteile anonymer Golang-Funktionen und -Verschlüsse May 05, 2024 am 09:54 AM

    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.

    See all articles