当前位置: 首页 > news >正文

v8引擎垃圾回收

V8引擎垃圾回收机制

v8引擎负责JavaScript的执行。V8引擎具有内置的垃圾回收机制,用于自动管理内存分配和释放

堆与栈

栈空间

栈空间是小而连续的内存空间,主要用于存储局部变量和函数调用的相关信息,同时栈结构是“先进后出”的策略

栈空间的最大的特点是空间连续,所以在栈中每个元素的地址都是固定的,因此栈空间的查找效率非常高,但是通常在内存中,很难分配到一块很大的连续空间,因此,V8 对栈空间的大小做了限制,如果函数调用层过深,那么 V8 就有可能抛出栈溢出的错误

  • 分配和释放速度快‌:栈上的资源分配和销毁只需要移动指针,因此速度非常快。
  • 固定大小‌:栈的空间是有限的,一旦函数调用层次过多或数据过大,就会导致栈溢出。
  • 遵循LIFO原则‌:后进先出,即最后进入栈的元素会被最先弹出。
堆空间

堆空间是一种形的存储结构,用来存储对象类型的离散的数据

  • 动态分配‌:堆上的内存空间是动态分配的,可以根据需要分配不同大小的内存块。
  • 灵活性高‌:堆可以存储各种类型的数据,包括对象、数组等复杂数据结构。
  • 管理复杂‌:由于堆的空间是动态分配的,管理起来相对复杂,容易出现内存泄漏等问题

回收策略

1》标记清除

这种算法在 JS 引擎中是最常用的(大部分浏览器都是V8引擎,使用的是标记清除)

大致过程:

首先标记内存中所有的变量(假设所有的都是垃圾,都标记为0);

然后将在上下文中的变量以及被上下文引用的变量的标记清除;

在此之后(离开环境时不再当前环境定义的变量被标记清除)的再被加上标记的变量就是待删除了

优点:

实现比较简单,打标记也无非打与不打两种情况,这使得一位二进制位(0和1)就可以为其标记,非常简单

缺点:

标记清除算法有一个很大的缺点,就是在清除之后,剩余的对象内存位置是不变的,也会导致空闲内存空间是不连续的,出现了 内存碎),并且由于剩余空闲内存不是一整块,它是由不同大小内存组成的内存列表,这就牵扯出了内存分配的问题

标记整理算法:在标记结束后,将活着的对象向内存的一端移动(将不需要清理的对象往内存一端移动),最后清理掉边界的内存

2》引用计数

大致过程:

声明变量并赋值的时候引用次数为1

当同一个值被赋值给另一个比那辆,引用书加1

如果对该值引用的变量被其他值覆盖了,引用书减1

如果引用次数为0时就可以被回收了

优点:

引用计数算法的优点我们对比标记清除来看就会清晰很多,首先引用计数在引用值为 0 时,也就是在变成垃圾的那一刻就会被回收,所以它可以立即回收垃圾

缺点:

首先它需要一个计数器,而此计数器需要占很大的位置,因为我们也不知道被引用数量的上限

其次,循环引用问题;对象A有一个指针指向对象B,而对象B也引用了对象A

对象A、B的引用次数都是2,在函数执行后,其实引用次数仍然时2;但是它们其实都不在作用域中了,属于可以回收的垃圾,但是内存并没有被释放

      function circleRef() {let A = new Object()let B = new Object()A.a = BB.b = A}circleRef()

想要释放必须在最后去掉引用关系

A=null
B=null

IE8及以前是使用的引用清除

V8引擎内存空间划分

‌**1》新生代(new space)**‌:用于存储新创建的对象。分为两部分,分别是‌使用去和空闲区

‌**2》老生代(old space)**‌:存储生存时间较长的对象。这些对象在新生代中存活一段时间后,会被移动到老生代。老生代内存区域相对较大,因为存储的是长期存活的对象,所以垃圾回收的频率相对较低。老生代内存区又分为老生代指针区和老生代数据区,前者包含大多数可能存在指向其他对象的指针的对象,后者只保存原始数据对象,这些对象没有指向其他对象的指针

‌**3》大对象区(Large Object Space)**‌:存放体积超过其他区域大小限制的大对象,这些对象由于体积较大,不会被频繁移动,因此放在单独的区域以避免影响其他对象的垃圾回收

‌**4》代码区(Code Space)**‌:存放JavaScript代码,这是唯一拥有执行权限的内存区域

‌**5》Map区(Map Space)**‌:用于存放Cell和Map,每个区域都是存放相同大小的元素,结构简单

6》Cell Space和Property Cell Space:用于存储固定大小的Cell对象和与JavaScript对象属性相关的PropertyCell对象,优化属性访问性能

V8引擎的垃圾回收策略

V8 设置了两个垃圾回收器,主垃圾回收器和副垃圾回收器;主垃圾回收器负责收集老生代中的垃圾数据,回收频率较低;副垃圾回收器负责收集新生代中的垃圾数据,回收相比更加频繁

可访问性分析法

V8引擎中采用了这种方法来判断是一个对象是否活跃,具体过程为:将一个称为GC Roots的对象(在浏览器环境中,GC Roots 可以包括:全局的 window 对象、所有原生DOM节点集合等等)作为所有初始存活的对象集合,从这个对象出发,进行遍历,遍历到的就认为是可访问的,为活动对象,需要保留;如果没有遍历到的对象,就是不可访问的,这些就是非活动对象,可能就会被垃圾回收。

新生代

新生代:主要用于存放存活时间较短的对象。使用scavenge算法进行回收

新生代回收过程:

scavenge算法主要使用了一种复制式的方法cheney算法(复制式的方法)来实现;

新生代空间被平等划分为两部分,from space 和to space; 当from space填满之后会进行一次垃圾回收,非存货对象被回收,存活的对象被复制到 to space,from space被清空,from space和to space进行了一次交换

scavenge算法是一种典型的牺牲空间换取时间的算法

新生代垃圾回收采用了并行机制。在新生代垃圾回收的过程中,副垃圾回收器使用并行机制,在整理排序阶段,即活动对象从from-space复制到to-space的时候,启用多个辅助线程并行进行整理。这种并行处理的方式意味着多个线程同时参与垃圾回收的过程,以提高效率。由于多个线程可能竞争同一个新生代的堆内存资源,可能会出现某个活动对象被多个线程进行复制操作的情况。为了解决这个问题,V8在第一个线程对活动对象进行复制完成后,必须去维护复制这个活动对象后的指针转发地址,以便于其他协助线程可以找到该活动对象后可以判断该活动对象是否已被复制。这种机制确保了新生代垃圾回收的正确性和效率‌

对象晋升(新生代变成老生代)

当一个对象在经过多次复制之后依旧存活,那么它会被认为是一个生命周期较长的对象,在下一次进行垃圾回收时,该对象会被直接转移到老生代中

晋升的条件:

  • 对象是否经历过一次Scavenge算法
  • 内存占比是否超过To空间的25%(避免内存使用过高影响后续的对象分配)

满足其中任意一个就会晋升

老生代

老生代采用Mark-Sweep(标记清除)Mark-Compact(标记整理)`来进行管理

老生代回收过程:

  1. 标记;递归遍历一组根元素,遍历能达到的元素是活动对象,达不到的是非活动对象 (Mark-Sweep)
  2. 清除;老生代垃圾回收器直接将非活动对象(数据、垃圾)清理掉 (Mark-Sweep)
  3. 整理;(Mark-Compact)

以下几种情况都可以作为根节点:

  1. 全局对象
  2. 本地函数的局部变量和参数
  3. 当前嵌套调用链上的其他函数的变量和参数

Mark-Sweep算法存在一个问题,就是在经历过一次标记清除后,内存空间可能会出现不连续的状态,因为我们所清理的对象的内存地址可能不是连续的,所以就会出现内存碎片的问题,导致后面如果需要分配一个大对象而空闲内存不足以分配,就会提前触发垃圾回收;所以通过Mark-Compact(标记整理)解决内存碎片的问题

一般 10 次Mark-Sweep会伴随一次Mark-Compact

策略优化

最开始的垃圾回收机制有两个大的缺点

  • 垃圾回收器在主线程上执行,执行垃圾回收期间会阻塞js执行
  • 一次执行一个完整的垃圾回收流程,阻塞时间还是连续的

对此V8做出了许多优化:

一般来说,老生代会保存大量存活的对象,如果在标记阶段将整个堆内存遍历一遍,那么势必会造成严重的卡顿。

因此,为了减少垃圾回收带来的停顿时间,V8引擎又引入了增量标记 的概念,即将原本需要一次性遍历堆内存的操作改为增量标记的方式,先标记堆内存中的一部分对象,然后暂停,将执行权重新交给JS主线程,待主线程任务执行完毕后再从原来暂停标记的地方继续标记,直到标记完整个堆内存。只有在浏览器的空闲时间才会执行对应的任务,否则延迟执行,尽可能少地影响主线程的任务,避免应用卡顿,提升应用性能。

得益于增量标记的好处,V8引擎后续继续引入了延迟清理 增量式整理,让清理和整理的过程也变成增量式的。同时为了充分利用多核CPU的性能,也将引入并行标记并行清理,进一步地减少垃圾回收对主线程的影响,为应用提升更多的性能

  • 增量标记:V8使用增量标记,即不是一次性遍历整个堆,而是分批次进行,使得每次正常执行之间的停顿非常短暂;即将原本需要一次性遍历堆内存的操作改为增量标记的方式,先标记堆内存中的一部分对象,然后暂停,将执行权重新交给JS主线程,待主线程任务执行完毕后再从原来暂停标记的地方继续标记,直到标记完整个堆内存
  • 延迟清理:在浏览器的空闲时间执行垃圾回收任务
  • 增量整理:一次整理一部分
  • 并发标记:允许垃圾回收的标记阶段与JavaScript代码执行并行进行,减少了主线程的暂停时间
  • 并行处理:多个辅助线程并行进行整理,提高了垃圾回收的效率

相关文章:

v8引擎垃圾回收

V8引擎垃圾回收机制 v8引擎负责JavaScript的执行。V8引擎具有内置的垃圾回收机制,用于自动管理内存分配和释放 堆与栈 栈空间 栈空间是小而连续的内存空间,主要用于存储局部变量和函数调用的相关信息,同时栈结构是“先进后出”的策略 栈…...

H5st5.0.0协议分析

签名核心:设备注册 5 8 9段签名校验 其中第八段主要收集了一些指纹信息 需要 对应一致 注册核心加密: fp localTk fp - 16位字符串 localTk - 92位字符串 tls指纹检测 py、js纯算皆可调用 注意:仅供学习交流,与作者无关&am…...

明达助力构建智能变电站新体系

背景概述 随着智能电网技术的飞速进步与电力需求的持续增长,变电站作为电力传输网络的核心节点,其运维效率及安全性能对电网的整体稳定运行起着决定性作用。传统的人工巡检和维护手段已难以匹配现代电网对高效性、实时性及智能化管理的迫切需求。因此&a…...

Flink优化----FlinkSQL 调优

目录 FlinkSQL 调优 1 设置空闲状态保留时间 2 开启 MiniBatch 3 开启 LocalGlobal 3.1 原理概述 3.2 提交案例:统计每天每个 mid 出现次数 3.3 提交案例:开启 miniBatch 和 LocalGlobal 4 开启 Split Distinct 4.1 原理概述 4.2 提交案例&…...

机器学习(二)-简单线性回归

文章目录 1. 简单线性回归理论2. python通过简单线性回归预测房价2.1 预测数据2.2导入标准库2.3 导入数据2.4 划分数据集2.5 导入线性回归模块2.6 对测试集进行预测2.7 计算均方误差 J2.8 计算参数 w0、w12.9 可视化训练集拟合结果2.10 可视化测试集拟合结果2.11 保存模型2.12 …...

01.01、判定字符是否唯一

01.01、[简单] 判定字符是否唯一 1、题目描述 实现一个算法,确定一个字符串 s 的所有字符是否全都不同。 在这一题中,我们的任务是判断一个字符串 s 中的所有字符是否全都不同。我们将讨论两种不同的方法来解决这个问题,并详细解释每种方法…...

第五届“传智杯”全国大学生计算机大赛(练习赛)水题题解

目录 复读 题目描述 输入格式 输出格式 输入输出 说明/提示 源代码 时钟 题目描述 输入格式 输出格式 输入输出 说明/提示 源代码 平等的交易 题目描述 输入格式 输出格式 输入输出 说明/提示 源代码 清洁工 题目描述 输入格式 输出格式 输入输出…...

iOS 苹果开发者账号: 查看和添加设备UUID 及设备数量

参考链接:苹果开发者账号下添加新设备UUID - 简书 如果要添加新设备到 Profiles 证书里: 1.登录开发者中心 Sign In - Apple 2.找到证书设置: Certificate,Identifiers&Profiles > Profiles > 选择对应证书 edit &g…...

推进数字园区建设-成都国际数字影像产业园

在当今数字化浪潮的席卷下,数字园区建设已成为推动区域经济发展、提升产业竞争力的关键举措。成都国际数字影像产业园作为数字产业领域的重要项目,以其独特的发展模式和创新实践,在推进数字园区建设方面取得了显著成效,为数字产业…...

oracle linux8.10+ oracle 23ai安装

介质准备: 数据库23ai https://edelivery.oracle.com 上述网站下载基础版本,本次未使用。 本次是安装了带补丁的版本: Database Release Update 23.6.0.24.10 GoldImage表示带补丁用于直接安装的软件包 查找888.1对应Primary Note for …...

PH热榜 | 2024-12-25

1. Assistive24 标语:为残障人士提供的免费辅助技术 介绍:Assistive24 是一款免费的 Chrome 浏览器扩展程序,可以帮助患有注意力缺陷多动障碍 (ADHD)、阅读障碍 (dyslexia) 和低视力等障碍的用户更方便地浏览网页。它提供语音导航、自定义…...

OpenCV相机标定与3D重建(36)计算两幅图像之间基本矩阵(Fundamental Matrix)的函数findFundamentalMat()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 从两幅图像中的对应点计算基本矩阵。 cv::findFundamentalMat 是 OpenCV 中用于计算两幅图像之间基本矩阵(Fundamental Matrix&#…...

ZLG嵌入式笔记 | 电源设计避坑(上)

产品上量后,通常都会有降成需求。多年来,接触过不少产品降成案例,在电源上下刀过猛,引发了产品偶发性问题,带来了很不好的负面影响。本文将对这些案例进行总结,提供电源设计参考,确保产品降成不…...

.NET能做什么?全面解析.NET的应用领域

.NET 是由微软开发的一个开源、跨平台的开发框架。它不仅支持构建各种应用程序,还能运行在不同的操作系统上,包括 Windows、Linux 和 macOS。自从 .NET Core 的推出,.NET 成为了一个现代化的开发平台,能够满足企业和开发者日益多样…...

初始JavaEE篇 —— 网络原理---传输层协议:深入理解UDP/TCP

找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏:JavaEE 目录 UDP协议 参数解析: 校验和的计算 TCP协议 参数解析: 确认应答机制 超时重传 连接管理 三次握…...

企业如何搭建安全的跨网文件安全交换管理系统

在数字化转型的浪潮中,企业对数据的安全性和流动性提出了前所未有的高要求。特别是在网络隔离的情况下,如何实现跨网的安全、高效的文件交换成为了众多企业迫切需要解决的问题。 这不仅是技术上的挑战,还涉及到企业内部管理流程的优化和安全策…...

2023 年 12 月青少年软编等考 C 语言四级真题解析

目录 T1. 移动路线T2. 公共子序列T3. 田忌赛马T4. 宠物小精灵之收服 T1. 移动路线 此题为 2021 年 12 月四级第一题原题,见 2021 年 12 月青少年软编等考 C 语言四级真题解析中的 T1。 T2. 公共子序列 此题为 2022 年 3 月四级第四题原题,见 2022 年 …...

GDPU Vue前端框架开发 期末赛道出勇士篇(更新ing)

记住,年底陪你跨年的不会仅是方便面跟你的闺蜜,还有孑的笔记。 选择题 1.下列选项用于设置Vue.js页面视图的元素是()。 A. Template B. script C. style D. title 2.下列选项中能够定义Vuejs根实例对象的元素是(&…...

老旧小区用电安全保护装置#限流式防火保护器参数介绍#

摘要 随着居民住宅区用电负荷的增加,用电安全问题日益突出,火灾隐患频繁发生。防火限流式保护器作为一种新型电气安全设备,能够有效预防因电气故障引发的火灾事故。本文介绍了防火限流式保护器的工作原理、技术特点及其在居民住宅区用电系统…...

7.C语言 宏(Macro) 宏定义,宏函数

目录 宏定义 宏函数 1.注释事项 2.注意事项 宏(Macro)用法 常量定义 简单函数实现 类型检查 条件编译 宏函数计算参数个数 宏定义进行类型转换 宏定义进行位操作 宏定义进行断言 总结 宏定义 #include "stdio.h" #include "string.h" #incl…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手:借助大模型技术,开发能根据用户输入的主题、风格等要求,生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用,帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)

服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异&#xff…...

什么是EULA和DPA

文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

【深度学习新浪潮】什么是credit assignment problem?

Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter

java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...

【iOS】 Block再学习

iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

【1】跨越技术栈鸿沟:字节跳动开源TRAE AI编程IDE的实战体验

2024年初,人工智能编程工具领域发生了一次静默的变革。当字节跳动宣布退出其TRAE项目(一款融合大型语言模型能力的云端AI编程IDE)时,技术社区曾短暂叹息。然而这一退场并非终点——通过开源社区的接力,TRAE在WayToAGI等…...