重学JavaScript高级(四):JavaScript的内存管理和闭包

JavaScript的内存管理和闭包

认识内存管理

  • 不管什么样的编程语言,在代码的执行过程中,都要给它分配内存的,不同的是有些编程语言需要 手动的管理内存,有些编程语言则是 自动的帮助我们管理内存

  • 不管以什么样的方式管理内存,内存的管理都会有以下几个生命周期

    • 第一步:分配申请你需要的内存
    • 第二步:使用分配的内存
    • 第三步:不需要使用时,对其进行释放

JavaScript的垃圾回收

  • 因为内存的大小 是有限的,所以当一些存放在内存中的数据不再使用的时候,我们就需要 对其进行释放,以便 腾出更多的内存空间

  • 手动管理内存的语言中,释放内存是十分低效的

  • 所以大部分 现代的编程语言都是有自己的垃圾回收机制

    • 垃圾回收机制 Garbage Collection 简称GC
    • 对于那些不再使用的对象,我们都称之为垃圾,需要进行回收
  • 但是GC怎么知道哪些对象不会再进行使用呢

常见的GC算法–引用计数(Reference counting)

  • 一个对象有一个引用指向它时,那么这个对象的引用就会+1
  • 当这个对象的引用为0的时候,这个对象就会被销毁
  • 但是有一个很大的弊端,就是会产生循环引用

常见的GC算法–标记清除(mark-Sweep)

  • 该算法的核心思想就是 可达性
  • 这个算法会设置一个 根对象,GC会定期从这个根开始,找到所有从根开始有 引用的对象,并做上标记,对于没有标记的对象,就认为是不可用的对象

V8的实现GC的算法

  • js引擎采用比较广泛的算法就是 标记清除算法,但是V8引擎对此又进行了更好的优化

  • 标记整理算法(Mark-Compact)

    • 与标记清除不同的是,对垃圾进行回收期间,会将没有被 清理的对象,进行 内存整理,整合空闲的空间,避免内存的碎片化
  • 分代收集–对象被分成两组:新的和旧的

    • V8引擎中,对象创建的时候,都是新的,会在不断的回收中慢慢的销毁
    • 那些长期没有被销毁的,则会变成旧的,而且检查的频次也会随之减少
  • 增量收集

    • 如果当前内存中有很多对象,如果试图一次遍历并且标记,需要耗费一些事件,会带来明显的延迟
    • 所以V8引擎试图,将垃圾收集工作分成几部分来做, 然后将这 几部分逐一进行处理,这样就会有很多微小的延迟,而不是很大的延迟
  • 闲时收集

    • GC 只会在CPU空闲的时候尝试运行,为了减少对代码的影响

JavaScript中的闭包

闭包的定义

  • 在计算机科学中对闭包的定义

    • 闭包:又称为词法闭包,或者函数闭包
    • 是在支持 头等函数的编程语言中,实现词法绑定的一种技术
    • 闭包在实现上是一个 结构体,它存储了 一个函数和一个关联的环境
  • 闭包的概念出现于60年代,最早实现闭包的程序是Scheme,而JS中有大量的设计是来源于Scheme的

  • MDN对JS闭包的解释

    • 一个函数和对其周围状态的引用捆绑在一起,这样的组合就是闭包
    • 也就是说闭包可以让我们在一个内层函数中,访问到外层函数的作用域(JS通过作用域链实现的)
    • 在JS中,每当创建一个函数,闭包就会在函数创建的同时被创建出来
  • 个人理解

    • 一个普通的function函数,如果它可以访问外层作用域的自由变量,那么这个函数和周围环境就是一个闭包
    • 从不严格的角度来说:JS中的所有函数都是闭包
    • 从严格的角度来说:JS中的一个函数,如果访问了外层作用域的变量,那么就是一个闭包

闭包的访问过程

  • 以下代码的内存过程(大概)

    • scope chain的指向是指向VO(GO、AO的)
    • 内存的指向会一直存在,随着代码量的增多,占用的内存会越来越大

image.png

JavaScript内存泄漏以及释放内存

  • 内存泄漏:对于那些永远不会再使用的对象,但是对于GC来说它不清楚,因此内存占用就会一直存在
  • 通过垃圾回收机制,我们可以知道,若标记的对象一直存在,那么GC就不会清除该对象
  • 我们只需要将adder5设置为null,那么adder5对应的对象,不可达了,所以GC就会将该内存回收

浏览器的优化操作

function foo(){
    let name = "zhangcheng";
    let age = 18;
    function fooin(){
        console.log(name)
    }
}
  • 在fooin中没有用到age,因此浏览器会做出相应的优化,在fooin闭包中不会有age的出现
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值