美文网首页JsWeb前端之路让前端飞
Javascript 基础夯实 —— 初识 Javascript

Javascript 基础夯实 —— 初识 Javascript

作者: ac68882199a1 | 来源:发表于2017-11-12 20:33 被阅读51次

    随着前端业务需求的不断增多,相比以前,我们会占用更多的内存。但是内存并不是无限的,而对于那些我们不再需要的变量、对象该怎么处理呢?难道一个一个去手动释放么?其实并不需要,Javascript 具有自动垃圾回收机制,会定期对那些我们不再使用的变量、对象所占用的内存进行释放

    Javascript 的垃圾回收机制

    Javascript 会找出不再使用的变量,不再使用意味着这个变量生命周期的结束。Javascript 中存在两种变量——全局变量和局部变量,全部变量的声明周期会一直持续,直到页面卸载

    而局部变量声明在函数中,它的声明周期从执行函数开始,直到函数执行结束。在这个过程中,局部变量会在堆或栈上被分配相应的空间以存储它们的值,函数执行结束,这些局部变量也不再被使用,它们所占用的空间也就被释放

    但是有一种情况的局部变量不会随着函数的结束而被回收,那就是局部变量被函数外部的变量所使用,其中一种情况就是闭包,因为在函数执行结束后,函数外部的变量依然指向函数内的局部变量,此时的局部变量依然在被使用,所以也就不能够被回收

    function func1 () {
          const obj = {}
    }
    
    function func2 () {
          const obj = {}
          return obj
    }
    
    const a = func1()
    const b = func2()
    

    上面这个例子中,func1 执行时为 obj 分配了一块内存,但是随着函数执行结束,obj 占用的空间也就被释放了;而 func2 执行时,也为 obj 分配了内存,但是由于 obj 最终被返回赋值给了 b 导致其依然被使用,所以 func2 中的 obj 占用的内存不会被释放

    垃圾回收的两种实现方式

    垃圾回收有两种实现方式,分别是标记清除引用计数

    标记清楚

    当变量进入执行环境时标记为“进入环境”,当变量离开执行环境时则标记为“离开环境”,被标记为“进入环境”的变量是不能被回收的,因为它们正在被使用,而标记为“离开环境”的变量则可以被回收

    function func3 () {
          const a = 1
          const b = 2
          // 函数执行时,a b 分别被标记 进入环境
    }
    
    func3() // 函数执行结束,a b 被标记 离开环境,被回收
    

    引用计数

    统计引用类型变量声明后被引用的次数,当次数为 0 时,该变量将被回收

    function func4 () {
        const c = {} // 引用类型变量 c的引用计数为 0
          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 将被回收
    }
    

    但是引用计数的方式,有一个相对明显的缺点——循环引用

    function func5 () {
          let f = {}
          let g = {}
          f.prop = g
          g.prop = f
          // 由于 f 和 g 互相引用,计数永远不可能为 0
    }
    

    像上面这种情况就需要手动将变量的内存释放

    f.prop = null
    g.prop = null
    

    在现代浏览器中,Javascript 使用的方式是标记清楚,所以我们无需担心循环引用的问题

    扫码关注前端周记公众号

    相关文章

      网友评论

        本文标题:Javascript 基础夯实 —— 初识 Javascript

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