美文网首页
闭包、内存泄漏与垃圾回收

闭包、内存泄漏与垃圾回收

作者: 阿秃 | 来源:发表于2021-03-11 20:00 被阅读0次

    摘抄:https://blog.csdn.net/Q846169253/article/details/81148290
    闭包就是能够读取其它函数内部变量的函数。
    由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解为“定义一个函数内部的函数"
    本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

    function makeFunc(){
        var name = "Mozilla";
        function displayName(){
            alert(name)
        }
        return displayName
    }
    const myFunc = makeFunc();
    myFunc()
    
    

    试一试结果:js中的函数形成了闭包,在本例子中,myFunc是执行makeFunc时创建的displayName函数实例的引用。displayName的实例维持了一个对它的词法环境(变量name存在与其中)的引用,因此,当myFunc被调用时,变量name仍然可用

    function makeAdd(x){
        return function(y){
            return x + y
        };
    }
    var a = makeAdd(5);
    var b = makeAdd(10);
    console.log(a(2)); //7
    console.log(b(2)); //12
    

    闭包的原理

    借助函数的立即执行、参数以及函数的return返回值,多创建了一层作用域。从而实现外部函数持续被引用而不能释放内存空间,将值存储下来

    闭包的作用

    闭包就是将函数内部和函数外部连接起来的一座桥梁。使得外部函数可以读取内部函数的变量,这些变量的值始终保持再内存中,不会被垃圾回收器回收。

    闭包如何从外部的作用域读取到内部作用域的东西

    那就是在函数的内部,再定义一个函数。将内部函数传递到所在词法作用域以外

    闭包的优点

    • 避免全局变量被污染
    • 方便调用上下文的局部变量
    • 加强封装性

    闭包的缺点

    • 闭包常驻内存,内存消耗很大
    • 可能导致内存泄漏
      解决方案:在退出函数之前,将不使用的局部变量全部删除
      如何删除?
    // 普通变量:将变量置为undefined
    var tt = 111;
    tt = undefined;
    //带有属性或者方法的, 用delete删除属性或方法
    delete tt.name 
    

    内存泄漏

    一块被分配的内存既不能被使用,也不能回收,从而影响性能,从而导致程序崩溃。
    内存泄漏起因:一般使用技术系统来处理内存,每个对象根据被引用对象多少来计数,当计数为零时,该对象就会被销毁,释放内存。而当两个对象循环引用时,计数始终为1,则永久性地占着内存。而闭包实际上非常容易造成js对象的dom对象的循环引用

    function ex(){
      var element = document.getElementByID('div1');
      element.onclick=function(){
          alert("aaa")
      }
    }
    

    ex()用匿名函数创建闭包,该DOM对象的onclick属性引用了匿名函数闭包,而闭包可以引用外部函数example()的整个活动对象,包括element;DOM(div1.onclick)--->JS(element) 由此形成了Javascript对象和DOM对象的隐藏循环引用。
    造成的内存泄漏
    解决方法:
    在js代码段运行完之后将形成循环引用的js对象设置为空
    function example(){
    var element = document.getElementByID("div1");
    element.onclick = function(){
    alert("This is a leak!")
    }
    element = null; //添加的语句
    }

    垃圾回收机制

    找到那些不再继续使用的变量,然后释放其占用的内存,垃圾收集器会按照固定的事件间隔周期性进行这一操作

    两种方法———标记清除和引用计数
    • 标记清除
      垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记,然后,它会去掉环境中的变量的标记和被环境中的变量引用的变量的标记,此后,如果变量再被标记则表示此变量准备被删除
      另一种解释:
      当变量进入执行环境时标记为“进入环境”,当变量离开执行环境时则标记为“离开环境”,而标记为“离开环境的变量则可以被回收”
    • 引用计数
      跟踪记录每个值被引用的次数,当声明一个变量并将一个引用类型的值赋值给该变量时,这个值的引用次数就是1,如果这个值再被赋值给另一个变量,则引用册数加1. 相反,如果一个变量脱离了该值的引用,则该值引用次数减1,当次数为0时,当次数为0时,就会等待垃圾回收器的回收。

    相关文章

      网友评论

          本文标题:闭包、内存泄漏与垃圾回收

          本文链接:https://www.haomeiwen.com/subject/jcljyktx.html