V8 垃圾回收机制

简介: V8 垃圾回收机制简单分享~

垃圾回收策略

垃圾回收有手动回收和自动回收两种策略。

手动回收需要自己控制内存的分配和销毁,如果分配了内存在使用结束后没有进行销毁,会造成内存泄漏。

而 JavaScript 采用的是另外一种策略即通过垃圾回收器自动回收的机制。

因为 JavaScript 中的数据存储在栈(原始数据类型)和堆(引用数据类型)中,所以它的垃圾回收也包含栈中的垃圾回收和堆中的垃圾回收两种。

栈中的垃圾回收

通过下面的一段代码,我们可以先看下调用栈中的垃圾是如何回收的。

function fn() {
    let num1 = 1;
    let obj1 = {test: "haha"};
    function fn2() {
        let num2 = 2;
        let obj2 = {test: "xixi"};
    }
    fn2();
}
fn();
AI 代码解读

执行到 fn2 时,此时调用栈和堆的状态如下图所示

image.png

从图中可以看出,原始类型的数据是分配在栈中的,对象这些引用类型的数据是分配在堆中的。

当 fn2 执行完的时候,fn2 所对应的栈中的数据就会被销毁掉,它是如何被销毁的呢?

在栈中有一个记录当前执行状态的指针 ESP,它指向当前执行函数的上下文,当 fn2 执行完的时候,这个指针就会下移到 fn 的执行上下文,这个下移的操作就是销毁 fn2 执行上下文的过程。

如果之后还有别的函数执行,那么该函数的执行上下文就会直接覆盖在原来 fn2 执行上下文的地方。

即当一个函数执行结束之后,JS 引擎会通过向下移动 ESP 来销毁该函数保存在栈中的执行上下文。

堆中的垃圾回收

当栈中的数据被回收掉之后,接下来我们看看堆中的数据是如何进行回收的。

要回收堆中的垃圾数据,就需要用到 JavaScript 的垃圾回收器。

V8 引擎把堆分为新生代和老生代两个区域,新生代中存放的是生存时间短的数据,老生代中存放的是生存时间长的数据。

新生区出于效率的考虑,一般比较小,只有 1-8 M 的容量,而老生区容量则大很多。这两个区域使用的垃圾回收器是不同的。新生代的垃圾是通过副垃圾回收器回收的,而老生代的垃圾是通过主垃圾回收器进行回收的。

垃圾回收器的工作流程

垃圾回收器的工作流程其实都是差不多的。

第一步是先对空间中的对象进行标记,将空间中的对象分为活动对象和非活动对象,非活动对象就是可以进行垃圾回收的对象。

第二步是回收非活动对象所占据的内存。就是在所有的标记都完成之后,对内存中所有标记为非活动对象进行清理。

第三步是进行内存整理。垃圾回收后,内存中可能会出现不连续的空间,如果之后需要分配较大的连续内存,那么这些不连续的空间就可能导致分配不了,所以我们需要对内存进行整理。不过内存整理这一步不是一定需要的,因为有些垃圾回收器在进行回收的时候不会产生内存碎片,例如我们下面要说到的副垃圾回收器。

副垃圾回收器

副垃圾回收器负责新生区的垃圾回收。除了占用内存比较大的对象,一般的对象都是分配到新生区的,所以新生区的垃圾回收相对老生区来说会更频繁。

副垃圾回收器使用 Scavenge 算法进行处理。该算法将新生区的空间进行对半划分,一个作为存储对象的区域,另外一个作为空闲区域。

新加入的对象都会放到对象区域,当对象区域快要满了的时候,就会执行垃圾回收。

副垃圾回收器先对对象区域中的垃圾进行标记,标记完成后就将活动对象有序地复制到空闲区域中,这样在垃圾清理的过程中也相当于完成了内存的整理,复制后的空闲区域就变成对象区域,而原来的对象区域则变成了空闲区域。这样就完成了垃圾的回收。

每当对象区域快满了的时候就会进行垃圾回收,所以对象区域和空闲区域也是不断进行翻转,可以无限重复地使用下去。

那么会有一个问题,新生区的空间不大,如果被装满了怎么办?为了解决这个问题,V8 引擎使用了对象晋升策略,如果一个对象经过两次垃圾回收依然存活着,那么它就会被移动到老生区中。

主垃圾回收器

从上面对副垃圾回收器的介绍中,我们可以看出来,老生区中的对象主要是占用内存比较大的对象和存活时间久的对象,其中占用内存大的对象是直接分配到老生区的。

因为老生区的对象比较大,如果采用和副垃圾回收器一样的回收策略的话,复制的操作需要花费比较长的时间,并且有一半的空间会被浪费掉,所以主垃圾回收器采用的是另外一种算法,标记-整理算法来进行垃圾回收。

首先是从一组根元素开始,递归遍历这组根元素,能遍历到的对象标记为活动对象,没有遍历到的对象标记为需要进行垃圾回收的非活动数据。

标记完之后就将所有活动对象向同一边进行移动,移动完之后就将端边界外的内存都清理掉,这样就完成了内存整理和垃圾回收。

增量标记算法

因为 JavaScript 是单线程的,在执行垃圾回收的时候无法执行其他任务,所以如果垃圾回收时间过长的话那么就会造成明显的卡顿。

因为新生区的空间较小,所以造成的影响也比较小,我们可以忽略不计,而老生区因为其空间比较大,所以垃圾回收的时间可能过长。

为了降低老生区垃圾回收造成的卡顿,V8 将垃圾回收中的标记过程分为一个个子标记过程,同时让垃圾回收标记和 JavaScript 逻辑的交替执行,直到标记阶段完成,这个算法就是增量标记算法。

通过将一个大的任务划分为一个个小的任务,就可以让垃圾回收和 JavaScript 逻辑都正常地进行,同时不影响用户的体验。

目录
打赏
0
0
0
0
1
分享
相关文章
Python如何接收键盘按键
本文介绍了Python处理键盘输入的方法,从基础的`input()`函数获取用户文本输入,到使用第三方库`pynput`监听键盘事件。`pynput`库允许开发者详细监控按键按下和释放,识别特殊键、获取修饰键状态以及设置热键组合。通过示例代码,读者可以学习如何在Python中实现键盘事件的实时响应,适用于游戏开发、用户界面等场景。
2025年API开发必备:10款优秀Postman替代工具大盘点
API测试在现代开发中至关重要,Postman虽为首选,但市场上涌现出许多优秀替代工具。本文精选2025年10款好评如潮的API测试工具:Apifox、Insomnia、Hoppscotch、Paw、Talend API Tester、HTTPie、ARC、Swagger UI、SoapUI和Thunder Client。这些工具各具特色,满足不同需求,如团队协作、开源易用、自动化测试等。无论是简洁轻量还是功能全面,总有一款适合你的团队,助力效率提升。
《打破知识壁垒:解锁自然语言处理模型跨领域知识图谱关联与推理密码》
在人工智能快速发展的背景下,自然语言处理(NLP)技术成为各行业智能化变革的关键。知识图谱作为结构化的语义知识库,通过“实体-关系-实体”三元组描绘现实世界的概念及其关系,为NLP模型提供背景知识和推理依据。然而,随着多领域知识的爆发式增长,如何实现不同领域知识图谱的有效关联与推理成为亟待解决的问题。本文探讨了理解领域特性、实体对齐、关系映射与融合及深度学习推理模型构建等关键步骤,旨在打破领域间知识壁垒,提升NLP技术的智能化水平,推动其在智能问答、推荐、决策辅助等领域的广泛应用。
243 1
微信小程序如何安装使用第三方包
本文档详细介绍了微信小程序开发中引入和使用第三方包的步骤。
619 3
Pillow:Python图像处理的强大工具
**Pillow**是Python的图像处理库,源自PIL,支持多种格式如JPEG、PNG等。本文介绍了Pillow的基本用法和高级特性。安装Pillow后,可通过`Image.open()`打开图像,再使用`resize()`、`crop()`、`rotate()`等方法进行图像操作,如缩放、裁剪和旋转。此外,Pillow还支持颜色转换、滤镜应用(如模糊)、图像增强(亮度、对比度调整)和处理流水线。在实际应用中,Pillow常用于生成网页缩略图、添加水印及配合机器学习库进行图像预处理。【6月更文挑战第6天】
319 1
C++框架设计中实现可扩展性的方法
在软件开发中,可扩展性至关重要,尤其对于C++这样的静态类型语言。本文探讨了在C++框架设计中实现可扩展性的方法:1) 模块化设计降低耦合;2) 使用继承和接口实现功能扩展;3) 通过插件机制动态添加功能;4) 利用模板和泛型提升代码复用;5) 遵循设计原则和最佳实践;6) 应用配置和策略模式以改变运行时行为;7) 使用工厂和抽象工厂模式创建可扩展的对象;8) 实现依赖注入增强灵活性。这些策略有助于构建适应变化、易于维护的C++框架。
758 2
什么?!通义千问也可以在线开发应用了?!
阿里巴巴推出的通义千问,是一个超大规模语言模型,旨在高效处理信息和生成创意内容。它不仅能在创意文案、办公助理、学习助手等领域提供丰富交互体验,还支持定制化解决方案。近日,通义千问推出代码模式,基于Qwen2.5-Coder模型,用户即使不懂编程也能用自然语言生成应用,如个人简历、2048小游戏等。该模式通过预置模板和灵活的自定义选项,极大简化了应用开发过程,助力用户快速实现创意。
Java中的异常处理:理解与实践
【9月更文挑战第9天】在Java编程的海洋里,异常处理是一艘不可或缺的救生艇。它不仅保护你的代码免受意外错误的侵袭,还能确保你的应用在遇到困难时能优雅地继续航行。本文将带你深入了解Java的异常处理机制,通过浅显易懂的方式,让你掌握如何捕捉和处理异常,以及如何自定义异常类型来应对特定的业务需求。无论你是Java新手还是资深开发者,这篇文章都将为你提供宝贵的知识和技巧,让你的代码更加健壮和可靠。
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问