JS垃圾回收机制

js运行生命周期

分配内存=》使用内存=》清理内存
现在所谈到的垃圾回收机制就是指的清理内存的过程。
js会自动为我们进行清理内存的操作,也就是内存回收机制,针对于不同数据类型表现为:

  • 简单数据结构内存保存在固定的栈空间,可以直接通过值进行访问
  • 引用数据类型的引用地址保存在栈空间,引用所指向的值保存在堆空间
    在栈内存中的数据可以通过操作系统进行处理,但是在堆内存中的数据类型则要通过js自身引擎的垃圾回收机制进行处理。

垃圾回收机制

简单来时,垃圾回收机制(GC——Garbage Collection)指的是一种定期找出不再用到的内存(变量)并清理释放内存的机制。

常见的算法策略

标记清除

机制:

  1. 运行时给所有堆内存的变量打上垃圾标记
  2. 从根对象遍历,把不是垃圾的节点(还在被引用的变量)去除标记
  3. 清理被标记的垃圾,释放其所占用的内存空间
  4. 把内存中的对象标记修改为垃圾标记,等待下一次垃圾回收
    优点:实现简单
    缺点:
  • 内存碎片化:被标记的对象清除后,内存变成了不连续的空间,影响着内存的下一次分配
  • 分配速度慢:下一次为新对象分配内存是,需要匹配其所占内存空间大小和现有碎片内存空间,最坏的情况会遍历完整个内存空间,使得分配效率变慢
标记整理

机制:类同于标记清除,不同的是在清除完成之后,会将剩下的对象向内存的一端移动,解决了内存碎片化的问题。

引用计数算法

机制:记录每个变量值被引用的次数,如果次数变为0,对象就会被回收,具体表现为:

  1. 声明变量并将引用类型赋值给变量、同一个值被赋给另一个变量——引用次数+1
  2. 变量值被其他值覆盖——引用次数-1
    优点:与标记清除算法每隔一段时间进行回收来比,垃圾可以被立即回收
    缺点:
  • 需要占用内存空间大的计数器
  • 无法解决循环引用无法回收的问题

V8对GC的优化

分代式垃圾回收

分代式垃圾回收将堆内存中的对象分为新生代对象和老生代对象,前者指新、小、存活时间短的对象,后者指大、老、存活时间长的对象,对于两个不同的区域,GC也采取了不同的GC策略。

老生代:标记整理算法
新生代:Scavenge算法-Cheney算法

将新生代区域分为使用区和空闲区,
机制详细为:

  1. 将新加入的对象放入使用区
  2. 使用区快写满时进行垃圾回收:
    * 标记使用区内对象
    * 拷贝标记后的对象到空闲区排序
    * 清理新生代区域所以垃圾
    * 将原先排序后的剩余未被标记的对象所在的空闲区作为新的使用区(交换使用区和空闲区)
  3. 经过垃圾回收后还存在于被交换后的使用区的对象,晋升为老生代内存的对象
分代式的优化点
并行回收

JavaScript 是一门单线程的语言,它是运行在主线程上的,那在进行垃圾回收时就会阻塞 JavaScript 脚本的执行,需等待垃圾回收完毕后再恢复脚本执行,我们把这种行为叫做全停顿。
所谓并行,也就是同时的意思,它指的是垃圾回收器在主线程上执行的过程中,开启多个辅助线程,同时执行同样的回收工作。
即主线程GC时,辅助线程也GC。

增量标记

增量就是将一次 GC 标记的过程,分成了很多小步,每执行完一小步就让应用逻辑执行一会儿,这样交替多次后完成一轮 GC 标记。

  • 解决增量标记中引发的被标记的对象引用关系被修改的问题
    * 三色标记法:白、黑、灰
    * 白色指的是未被标记的对象
    灰色指自身被标记,成员变量(该对象的引用对象)未被标记
    黑色指自身和成员变量皆被标记
    * 写屏障机制:一旦有黑色对象引用白色对象,该机制会强制将引用的白色对象改为灰色,从而保证下一次增量 GC 标记阶段可以正确标记。
惰性清理

当增量标记完成后,假如当前的可用内存足以让我们快速的执行代码,也没必要立即清理内存的,可以将清理过程稍微延迟一下,让 JavaScript 脚本代码先执行,也无需一次性清理完所有非活动对象内存,可以按需逐一进行清理直到所有的非活动对象内存都清理完毕,后面再接着执行增量标记

并发回收

主线程在执行 JavaScript 的过程中,辅助线程能够在后台完成执行垃圾回收的操作,辅助线程在执行垃圾回收的时候,主线程也可以自由执行而不会被挂起。
即主进程JS,辅助线程GC。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值