• 循环引用

    循环引用会造成无法进行垃圾回收

    function f() {
      var o1 = {};
      var o2 = {};
      o1.P = O2; // O1 引用 o2
      o2.p = o1; // o2 引用 o1. 这就造成循环引用
    }
    
    f();

    img

  • 标记-清除算法

    通过根变量是否可达,来判断是否为激活状态

    img

    解决了循环引用无法回收的问题,通过判断根变量是否可达来决定是否回收

    img

  • 内存泄漏

    一些程序在过去使用,但是现在处于闲置状态,却没有返回给操作系统或者可用内存池。

    JS中存在的内存泄露

    • 变量未声明被提升到全局变量

      function sayHello(){
          timeStr=Date.now();
          console.log(timeStr);
      }
      //timerStr为全局变量
      sayHello();
    • 使用this关键字创建的全局变量

      function sayHello(){
          this.timeStr=Date.now();
          console.log(timeStr);
      }
      //timerStr为全局变量
      sayHello();

      解决上面两个问题,可以在js文件头部添加'use strict'来开启严格模式

    • 定时器及被遗忘的回调函数

    • 闭包

    • 移除 DOM 引用

      var elements = {
        button: document.getElementById('button'),
        image: document.getElementById('image')
      };
      
      function doStuff() {
        elements.image.src = 'http://example.com/image_name.png';
      }
      
      function removeImage() {
          // image 元素是 body 元素的直系后代元素
          document.body.removeChild(document.getElementById('image'));
          // 这时,我们仍然在 elements 全局对象中引用了 #button 元素
          // 换句话说,按钮元素仍然在内存中且不能够被垃圾回收器收集
      }
    • console.log 的对象不会被垃圾回收

    • ImageData 对象是 JS 内存杀手

  • 参考链接