zoukankan      html  css  js  c++  java
  • javascript常见内存泄露

    一、全局变量引起的内存泄漏

    function func(){
      lmw = 123456 //lmw是全局变量,不会被释放   
    }
    

     二、闭包引起的内存泄漏

    function func(){
      var lmw = 123456;//闭包环境,不会被释放
      function lmw2(){
        //就算是一个空函数,也不会释放
      }
      return lmw2 //被暴露在外界,随时可能被引用
    }
    

     三、子元素存在引用引起的内存泄漏

    var select = document.querySelector;
    var treeRef = select('#tree');
    
    var leafRef = select('#leaf');   //在COM树中leafRef是treeFre的一个子结点
    
    select('body').removeChild(treeRef);//#tree不能被回收入,因为treeRef还在

    解决方法:

    treeRef = null;//tree还不能被回收,因为叶子结果leafRef还在
    leafRef = null;//现在#tree可以被释放了

    四、定时器泄露

    var  timer=null
    for(var  i=0;i<5;i++){
        var funcObj = {
            "handle":function(){
                var _this = this;
                timer = setTimeout(function(){
                    console.log(_this)
                    _this.handle()
                },9000)
            }
        }
    }
    funcObj.handle()
    funcObj = null //只是改变funcObj存储在栈里的引用地址,堆里保存的真实对象不会被释放,定时器还在引用
    console.log(funcObj)

    真正的释放还要清除定时器,再把funcObj = null

    clearTimeout(timer)
    funcObj = null
    console.log(funcObj)

    五、循环引用

    function fn() {
     var a = {};
     var b = {};
     a.pro = b;
     b.pro = a;
    }
     
    fn();
    以上代码a和b的引用次数都是2,fn()执行完毕后,两个对象都已经离开环境,在标记清除方式下是没有问题的,但是在引用计数策略下,因为a和b的引用次数不为0,所以不会被垃圾回收器回收内存,如果fn函数被大量调用,就会造成内存泄露。在IE7与IE8上,内存直线上升。
    IE中有一部分对象并不是原生js对象。比如,DOM和BOM中的对象就是使用C++以COM对象的形式实现的,而COM对象的垃圾回收机制采用的就是引用计数策略。因此,即使IE的js引擎采用标记清除策略来实现,但js访问的COM对象依然是基于引用计数策略的。
    换句话说,只要在老IE中涉及COM对象,就会存在循环引用的问题
    var element = document.getElementById("some_element");
    var myObject = new Object();
    myObject.e = element;
    element.o = myObject;
    
    
    这个例子在一个DOM元素(element)与一个原生js对象(myObject)之间创建了循环引用。其中,变量myObject有一个名为e的属性指向element对象;而变量element也有一个属性名为o回指myObject。由于存在这个循环引用,即使例子中的DOM从页面中移除,它也永远不会被回收。
    解决方法:
    myObject.e= null;
    element.o = null;
    再来看一个在日常开发中容易犯错的例子:
    window.onload=function outerFunction(){
     var obj = document.getElementById("element");
     obj.onclick=function innerFunction(){};
    };
    这段代码看起来没什么问题,但是obj引用了document.getElementById(“element”),而document.getElementById(“element”)的onclick方法会引用外部环境中的变量,自然也包括obj。
    解决方法:
    window.onload=function outerFunction(){
     var obj = document.getElementById("element");
     obj.onclick=function innerFunction(){};
     obj=null;
    };
    
    
    将变量设置为null意味着切断变量与它此前引用的值之间的连接。当垃圾回收器下次运行时,就会删除这些值并回收它们占用的内存。
    在上面描述的循环引用例子,还可以理解成闭包循环引用导致的内存泄漏
    当对DOM元素进行其他操作时,仍然要处处留心。只要是将JavaScript对象指定给DOM元素,就可能在旧版本IE中导致内存泄漏。jQuery只是有助于减少发生这种情况的可能性

    注意:IE9+并不存在循环引用导致Dom内存泄露问题

     
  • 相关阅读:
    Kafka 生产者 自定义分区策略
    同步互斥
    poj 1562 Oil Deposits(dfs)
    poj 2386 Lake Counting(dfs)
    poj 1915 KnightMoves(bfs)
    poj 1664 放苹果(dfs)
    poj 1543 Perfect Cubes (暴搜)
    poj 1166 The Clocks (暴搜)
    poj 3126 Prime Path(bfs)
    处理机调度
  • 原文地址:https://www.cnblogs.com/liumingwang/p/6769774.html
Copyright © 2011-2022 走看看