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(标记整理)`来进行管理
老生代回收过程:
- 标记;递归遍历一组根元素,遍历能达到的元素是活动对象,达不到的是非活动对象 (Mark-Sweep)
- 清除;老生代垃圾回收器直接将非活动对象(数据、垃圾)清理掉 (Mark-Sweep)
- 整理;(Mark-Compact)
以下几种情况都可以作为根节点:
- 全局对象
- 本地函数的局部变量和参数
- 当前嵌套调用链上的其他函数的变量和参数
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…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

12.找到字符串中所有字母异位词
🧠 题目解析 题目描述: 给定两个字符串 s 和 p,找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义: 若两个字符串包含的字符种类和出现次数完全相同,顺序无所谓,则互为…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...