JS的垃圾回收

一、什么是垃圾回收

  JS垃圾回收机制的目的是为了防止内存泄漏,内存泄漏是指有一些已经不被需要的变量但仍然存在在内存中,这样便会造成内存泄漏。垃圾回收机制就是为了回收这些不被需要的变量,并且释放掉他们所指向的内存。

  Java、JavaScript等一些语言有垃圾回收机制,但是C\C++没有。其实我也不是很清楚为什么会有这样的区别。请知道的dalao可以评论告诉我一下!!!谢谢么么哒

 

二、JS垃圾回收的方法

  • 标记清除
    • 这是最常见的回收方法,也是大部分浏览器使用的回收方法。
    • 当变量进入执行环境是,就会被标记上“进入环境”,从逻辑上讲,被标记上“进入环境”的变量所指向的内存是永远不会被回收的。当某个变量离开执行环境时,就会被标上“离开环境”。被标记为“离开环境”的变量则是可以回收的。
      function func() {
          const a = 1;
          const b = 1;
          // 此时变量a, b 分别被标记为 进入环境      
      }
      
      func();      // 函数执行完毕,a, b 被标记为 离开环境,此时a, b 被回收

       

  • 引用计数
    • 这是一种不太常见的回收方式。引用计数法就是同级引用类型声明后被引用的次数,当次数为0时,该变量就会被回收。
  • 存在缺点,会存在内存泄漏。
    // 正常的引用计数
    function func() {
        const c = {};
        let d = c;      // c 被 d 引用一次,c的引用计数为 1
        let e = c;      // c 被 e 引用一次,c的引用计数为 2
        d = {};        // d 不再引用c,c的引用计数减为 1
        e = null;      // e 也不在引用c,c的引用计数减为 0,此时c将会被回收
    }
    
    
    
    // 有缺陷的引用计数,内存泄漏
    function func() {
        let f = {};    
        let g = {};
        f.prop = g;
        g.prop = f;
        // 由于 f 和 g 相互引用,计数永远不为0
    }

 

三、有可能造成内存泄漏的案例

  • 全局变量造成的内存泄漏
  • 未销毁的定时器和回调函数造成的内存泄漏
  • DOM引用造成的内存泄漏
    var elements = {
        txt: document.getElementById('test');
    }
    
    function fn(){
        elements.txt.innerHTML = '11111';
    }
    
    function removeTxt(){
        document.body.removeChild(document.getElementById('test'));
    }
    
    fn();
    removeTxt();
    console.log(element.txt);      // <div id='test'>11111</div>
    
    
    // 虽然我们已经移除了id为text的元素,但我们认为无法对此进行回收。

     

posted @ 2019-09-17 00:29  瓶子咕咕咕  阅读(1442)  评论(0编辑  收藏  举报