Heim  >  Artikel  >  Web-Frontend  >  So lösen Sie den Garbage-Collection-Mechanismus und häufige Speicherverlustprobleme bei der JS-Elevation

So lösen Sie den Garbage-Collection-Mechanismus und häufige Speicherverlustprobleme bei der JS-Elevation

不言
不言Original
2018-07-09 10:26:361413Durchsuche

Dieser Artikel stellt hauptsächlich vor, wie man den Garbage-Collection-Mechanismus und häufige Speicherverlustprobleme in JS löst. Jetzt kann ich ihn mit Ihnen teilen

Vorwort

Der Grund dafür ist, dass ich den Speicherverlustmechanismus von Schließungen verstehen wollte und mich dann an die Analyse des Garbage-Collection-Mechanismus in „JS Advanced Programming“ erinnerte. Aber ich werde es verstehen, wenn ich nach einem Jahr zurückblicke, schreibe, um es mit allen zu teilen. Wenn es Ihnen gefällt, können Sie es liken/folgen und unterstützen.


Speicherlebenszyklus:

  1. Ordnen Sie den Speicher zu, den Sie benötigen:

Aufgrund von Zeichenfolgen und Objekten Keine feste Größe. Jedes Mal, wenn ein js-Programm eine Zeichenfolge oder ein Objekt erstellt, reserviert es Speicher zum Speichern dieser Entität .

  1. Machen Sie etwas mit dem zugewiesenen Speicher.

  2. Geben Sie es frei und geben Sie es zurück, wenn es nicht mehr benötigt wird:

Wenn Zeichenfolgen und Objekte nicht mehr benötigt werden, muss der von ihnen belegte Speicher gelöscht werden freigegeben. Andernfalls wird der gesamte verfügbare Speicher im System verbraucht, was zum Absturz des Systems führt. Dies ist die Bedeutung des Garbage-Collection-Mechanismus.

Der sogenannte Speicherverlust bezieht sich auf : Aufgrund von Nachlässigkeit oder Fehler gibt das Programm nicht mehr verwendeten Speicher nicht frei, was zu einer Speicherverschwendung führt.


Garbage-Collection-Mechanismus:

In Sprachen wie C und C++ muss der Speicher manuell verwaltet werden, was auch die Ursache vieler unnötiger Probleme ist. Glücklicherweise werden beim Schreiben von js die Speicherzuweisung und das Speicherrecycling vollständig automatisch verwaltet, und wir müssen uns über solche Dinge keine Sorgen machen.

Prinzip des Garbage-Collection-Mechanismus:

Der Garbage Collector findet in regelmäßigen Abständen Variablen, die nicht mehr verwendet werden, und gibt dann den von ihnen belegten Speicher frei.

Was ist eine Variable, die nicht mehr verwendet wird?

Variablen, die nicht mehr verwendet werden, sind Variablen, die ihren Lebenszyklus beendet haben und lokale Variablen sind, die nur während der Ausführung der Funktion vorhanden sind, es gibt keine anderen Referenzen (. Schließungen). Dann wird die Variable zum Recycling markiert.

Der Lebenszyklus globaler Variablen endet erst, wenn der Browser die Seite entlädt, was bedeutet, dass globale Variablen nicht als Garbage Collection behandelt werden.

Markenlöschung: die aktuell angewandte Garbage-Collection-Strategie

Arbeitsprinzip:

Wenn eine Variable in die Umgebung eintritt (z. B. Deklaration einer Variablen in einer Funktion), markieren Sie die Variable als „Umgebung betreten“, wenn eine Variable die Umgebung verlässt, wird sie als „Umgebung verlassen“ markiert. Der mit „Verlassen der Umwelt“ gekennzeichnete Speicher wird recycelt.

Workflow:

  1. Der Garbage Collector markiert alle im Speicher während des Betriebs gespeicherten Variablen.

  2. Entfernen Sie die Variablen in der Umgebung und die Tags von Variablen, auf die Variablen in der Umgebung verweisen.

  3. Die Variablen mit

    -Tags, die noch vorhanden sind, werden als Variablen betrachtet, die zum Löschen bereit sind.

  4. Schließlich führt der Garbage Collector den letzten Schritt der Speicherbereinigung durch,

    zerstört diese markierten Werte und gewinnt den von ihnen belegten Speicherplatz zurück .

Seit 2008 verwenden IE, Chrome, Fireofx, Safari und Opera

alle die Mark-and-Sweep-Garbage-Collection-Strategie , die Garbage-Collection-Zeitintervalle sind jedoch unterschiedlich unterschiedlich. Es gibt Unterschiede.

Referenzzählung: veraltete Garbage-Collection-Strategie

Zirkelreferenz: eine Technik zum Verfolgen jedes referenzierten Werts

In älteren Browsern (ja, wieder IE), BOM- und DOM-Objekte unten IE9 werden in Form von COM-Objekten mit C++ implementiert.

Der Garbage-Collection-Mechanismus von COM verwendet eine Referenzzählstrategie. Dieser Mechanismus kann niemals Speicher freigeben, wenn ein Zirkelverweis auftritt.

    var element = document.getElementById('something');
    var myObject = new Object();
    myObject.element = element; // element属性指向dom
    element.someThing = myObject; // someThing回指myObject 出现循环引用(两个对象一直互相包含 一直存在计数)。
Die Lösung besteht darin, die Links manuell zu trennen, wenn wir sie nicht verwenden:

     myObject.element = null; 
     element.someThing = null;

Eliminierung:

IE9 entfernt BOM- und DOM-Objekte In ein echtes JS-Objekt konvertiert, wodurch die Verwendung dieser Garbage-Collection-Strategie vermieden wird und die Hauptursache für häufige Speicherlecks unter IE9 beseitigt wird.

Es gibt ein Leistungsproblem mit einer verwirrenden Anweisung unter IE7. Schauen wir uns das an:

  1. 256 Variablen, 4096 Objekt- (oder Array-)Literale oder 64-KB-Strings , Das Erreichen eines kritischen Werts löst die Ausführung des Garbage Collectors aus.

  2. Wenn ein js-Skript während seines gesamten Lebenszyklus so viele Variablen behält, wird der Garbage Collector häufig weiter ausgeführt, was zu ernsthaften Leistungsproblemen führt.

IE7 hat dieses Problem behoben.


Welche Situationen können zu Speicherverlusten führen?

Obwohl es einen Garbage-Collection-Mechanismus gibt, können einige Situationen beim Schreiben von Code immer noch zu Speicherverlusten führen. Achten Sie darauf, sie beim Schreiben von Programmen zu vermeiden.

Unerwartete globale Variablen:

Wir haben oben erwähnt, dass

globale Variablen nicht durch Müll gesammelt werden Manchmal tritt in unserer Codierung die folgende Situation auf:

    function foo() {
     this.bar2 = '默认绑定this指向全局' // 全局变量=> window.bar2
      bar = '全局变量'; // 没有声明变量 实际上是全局变量=>window.bar
    }
    foo();

当我们使用默认绑定,this会指向全局,this.something也会创建一个全局变量,这一点可能很多人没有注意到。

解决方法:在函数内使用严格模式or细心一点

    function foo() {
      "use strict"; 
      this.bar2 = "严格模式下this指向undefined"; 
      bar = "报错";
    }
    foo();

当然我们也可以手动释放全局变量的内存

    window.bar = undefined
    delete window.bar2

被遗忘的定时器和回调函数

不需要setInterval或者setTimeout时,定时器没有被clear,定时器的回调函数以及内部依赖的变量都不能被回收,造成内存泄漏。

var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        node.innerHTML = JSON.stringify(someResource));
        // 定时器也没有清除
    }
    // node、someResource 存储了大量数据 无法回收
}, 1000);

解决方法: 在定时器完成工作的时候,手动清除定时器。

闭包:

闭包可以维持函数内局部变量,使其得不到释放,造成内存泄漏

    function bindEvent() {
      var obj = document.createElement("XXX");
      var unused = function () {
          console.log(obj,'闭包内引用obj obj不会被释放');
      };
      // obj = null;
    }

解决方法:手动解除引用,obj = null

循环引用问题

就是IE9以下的循环引用问题,上文讲过了。

没有清理DOM元素引用:

    var refA = document.getElementById('refA');
    document.body.removeChild(refA); // dom删除了
    console.log(refA, "refA");  // 但是还存在引用 能console出整个p 没有被回收

不信的话,可以看下这个dom。

解决办法:refA = null;

console保存大量数据在内存中。

过多的console,比如定时器的console会导致浏览器卡死。

解决:合理利用console,线上项目尽量少的使用console,当然如果你要发招聘除外。


如何避免内存泄漏:

记住一个原则:不用的东西,及时归还,毕竟你是'借的'嘛

  1. 减少不必要的全局变量,使用严格模式避免意外创建全局变量。

  2. 在你使用完数据后,及时解除引用(闭包中的变量,dom引用,定时器清除)。

  3. 组织好你的逻辑,避免死循环等造成浏览器卡顿,崩溃的问题。

关于内存泄漏:

  1. 即使是1byte的内存,也叫内存泄漏,并不一定是导致浏览器崩溃、卡顿才能叫做内存泄漏。

  2. 一般是堆区内存泄漏,栈区不会泄漏。

基本类型的值存在内存中,被保存在栈内存中,引用类型的值是对象,保存在堆内存中。所以对象、数组之类的,才会发生内存泄漏

  1. 使用chorme监控内存泄漏,可以看一下这篇文章


结语

了解了内存泄漏的原因以及出现的情况,那么我们在编码过程中只要多加注意,就不会发生非常严重的内存泄漏问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!

相关推荐:

原生JS基于window.scrollTo()封装垂直滚动动画工具函数

JavaScript创建对象的四种方式

利用javascript判断浏览器类型

Das obige ist der detaillierte Inhalt vonSo lösen Sie den Garbage-Collection-Mechanismus und häufige Speicherverlustprobleme bei der JS-Elevation. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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