一文带你搞懂V8垃圾回收系统

 更新时间:2023年07月28日 08:22:40   作者:荣达  
在V8中,JavaScript的内存空间分为栈(Stack)和堆(Heap)两部分,垃圾回收的基本思路是:查找内存中的所有变量,看哪些已经不再需要,然后释放这些变量所占用的内存,本文就给大家梳理一下V8垃圾回收系统,需要的朋友可以参考下

内存中两种变量的存储

在V8中,JavaScript的内存空间分为栈(Stack)和堆(Heap)两部分。栈用于存储原始类型,如Number,String,Boolean,Null,Undefined,Symbol以及引用对象的内存地址,而堆用于存储引用类型的对象。

垃圾回收的基本思路是:查找内存中的所有变量,看哪些已经不再需要,然后释放这些变量所占用的内存。

所以V8中的垃圾回收可以分为栈回收堆回收

栈回收

在V8引擎中,函数调用的参数、返回地址和局部变量都存储在调用栈中。每当一个函数被调用时,都会创建一个新的栈帧,其中包含这些信息。而栈帧的回收则非常直接:一旦函数调用结束,其栈帧就会被立即移除。这种机制依赖于ESP(Extended Stack Pointer)指针,该指针始终指向栈的顶部,用于追踪哪些栈帧是活动的,哪些可以被安全回收。

简单理解:说白了就是某个作用域代码执行完毕后,自动回收作用域内所有的普通数据类型的垃圾。

堆回收

堆中变量存储的分类

V8引擎引入所谓的“代际假说”,即“大部分对象在内存中存在的时间很短”,所以把堆内存分为新生代老生代两部分,新生代即对象一开始创建时存放的区域,一旦对象满足了一定的条件(也就是V8认为其会长时间存在于内存),那么它就会被移动(“晋升”)至老生代。

所以针对堆内存中的垃圾回收,也分为两种算法来分别处理新老生代。

新生代垃圾回收

采用Scavenge算法,简单来说就是Copy,也叫新生代互换。

结合上图:新生代空间等分成From空间与To空间,新声明的变量存放到新生代的From空间,直到From空间满了,这时候需要进行GC的垃圾回收。GC会根据代码分析出哪些obj不是垃圾,然后把非垃圾的obj对象直接copy到To空间,最后把From空间中的垃圾进行删除即可,至此存放对象的To空间变成From空间,原本的From空间变成To空间,从而开启新一轮的对象存储。

之所以新生代采用这种回收算法,可以从时空复杂度进行分析,首先我们会发现新生代的空间在同一时刻只有一半被利用,把空间进行了折半,目的就是为了对象转移时直接进行copy操作(肯定耗时非常低),可以理解为空间换时间。

并且新生代的总空间相较于老生代比较小,所以折半空间不会损失太多的内存空间,可以接受。

老生代垃圾回收

标记清除

在V8引擎早期,采用的是Mark-Sweep算法(标记清除),如下图:

注:上面图示的GC根节点并不是指浏览器的window对象,但可以类比window对象,我们可以通过window.xxx.xxx.xx访问所有的变量,自然可以通过GC的根节点访问所有的内存对象,一旦GC断开了与某个对象的联系,那么这个对象就可以理解为垃圾。

标记清除算法的完整步骤:

  • 从GC的根节点开始进行“广度扫描”(专属术语)并把非垃圾进行标记
  • 清除未被标记的对象

标记整理

现阶段Mark-Compact算法(标记整理)已经成为主流,如下图:

标记整理算法步骤:

  • 先进行广度扫描并标记非垃圾变量
  • 整理非垃圾变量的位置,目的是获取更大的连续空间,如上图一到图二(整理的过程中会对一些垃圾进行覆盖,可以理解为先整理后清除的原因)
  • 垃圾清除

也就是相较于标记清除算法多了一步:在垃圾清除之前进行内存空间的整理

标记算法优化

如上我们所描述的标记,都是“全停顿标记”,也就是说js主线程切换至GC垃圾回收线程时,在GC线程中会把所有的应该标记的变量都进行标记,然后进行大规模的清除。

这种标记算法的劣势就是时间开销大,导致GC线程占用的时间长,阻塞js主线程的运行。所以后期标记算法也进行了优化,衍生出来增量标记与三色标记法,这里就不详细记录了,总之优化的核心思想就是部分标记,从而减少GC线程对js线程运行时间的抢占。

plus

当然更早期的IE浏览器还使用过引用计数的堆回收算法,存在着不能解决循环引用问题等痛点。这里不再赘述。

到此这篇关于一文搞懂V8垃圾回收系统的文章就介绍到这了,更多相关V8垃圾回收系统内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)

    vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)

    本篇文章主要介绍了vue mint-ui 实现省市区街道4级联动(仿淘宝京东收货地址4级联动),非常具有实用价值,需要的朋友可以参考下
    2017-10-10
  • 使用vue打包进行云服务器上传的问题

    使用vue打包进行云服务器上传的问题

    这篇文章主要介绍了使用vue打包进行云服务器上传,本文给大家介绍的非常详细,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • 将VUE项目部署到服务器的详细步骤

    将VUE项目部署到服务器的详细步骤

    经过一段时间的探索,前端后端都有大致的样子了,下面就是部署到服务器,这篇文章主要给大家介绍了关于将VUE项目部署到服务器的详细步骤,文中通过图文介绍的非常详细,需要的朋友可以参考下
    2022-08-08
  • vue中动态修改img标签中src的方法实践

    vue中动态修改img标签中src的方法实践

    本文主要介绍了vue中动态修改img标签中src的方法实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Vue.component的属性说明

    Vue.component的属性说明

    这篇文章主要介绍了Vue.component的属性说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • Vue脚手架安装时遇到的无法安装问题详解

    Vue脚手架安装时遇到的无法安装问题详解

    开发中遇到bug是在正常不过了,而程序也基本都是bug堆里爬出来的,下面这篇文章主要给大家介绍了关于Vue脚手架安装时遇到的无法安装问题的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • vue组合式API浅显入门示例详解

    vue组合式API浅显入门示例详解

    这篇文章主要为大家介绍了vue组合式API浅显入门示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Vue中实现3D标签云的详细代码

    Vue中实现3D标签云的详细代码

    本文通过实例代码给大家介绍vue实现3D标签云的方法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-07-07
  • vue3使用vue-router的完整步骤记录

    vue3使用vue-router的完整步骤记录

    Vue Router是Vue.js (opens new window)官方的路由管理器,它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌,这篇文章主要给大家介绍了关于vue3使用vue-router的相关资料,需要的朋友可以参考下
    2021-06-06
  • Vue3使用transition组件改变DOM属性的方式小结

    Vue3使用transition组件改变DOM属性的方式小结

    这篇文章主要为大家详细介绍了Vue3中使用transition组件改变DOM属性的常用方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-01-01

最新评论