自动化的内存管理技术之垃圾回收机制-JavaScript引用数据内存回收机制

垃圾回收机制(Garbage Collection, GC) 是一种自动化的内存管理技术,用于回收程序中不再使用的内存空间,避免内存泄漏。JavaScript(尤其是 V8 引擎)使用了一些经典的垃圾回收算法,如 标记-清除分代回收

以下是垃圾回收的原理和具体机制的详细解析:


1. 垃圾回收的核心目标

垃圾回收的主要任务是:

  1. 找出不再被引用的对象(不可达的对象)。
  2. 释放这些对象所占用的内存空间。
  3. 确保程序有充足的内存可以继续运行。

2. 常见垃圾回收算法

(1) 标记-清除算法(Mark-and-Sweep)

这是最基础、最常用的垃圾回收算法。

工作原理
  1. 标记阶段(Marking Phase)

    • 从根对象(如全局对象、栈中的局部变量)出发,递归检查每个对象是否可以到达。
    • 所有可达的对象都会被标记为“活跃”状态。
  2. 清除阶段(Sweeping Phase)

    • 遍历整个内存区域,回收没有被标记的“不可达”对象,并释放它们占用的内存。
示意图
初始内存状态:
[根对象] --> [对象A] --> [对象B]
                      [对象C](无引用)

标记阶段:
根对象、对象A、对象B 被标记为“活跃”。
对象C 被标记为“不可达”。

清除阶段:
回收对象C。
优点
  • 简单高效,适合大多数情况。
缺点
  • 垃圾回收期间可能暂停程序执行(称为“停顿”),影响性能。

(2) 分代回收算法(Generational GC)

现代 JavaScript 引擎(如 V8)引入了分代垃圾回收机制,将内存划分为两代:

  • 新生代:存放短期存活的对象(如局部变量、临时对象)。
  • 老生代:存放长期存活的对象(如全局对象、大型缓存)。
工作原理
  1. 新生代和老生代分别使用不同的垃圾回收策略:

    • 新生代垃圾回收:采用Scavenge算法,因为新生代中的大多数对象存活时间短,清理时只关注少量存活对象。
    • 老生代垃圾回收:采用标记-清除标记-整理算法,因为老生代中对象存活时间较长,内存碎片化问题更严重。
  2. 当新生代的对象存活时间足够长时,会被移动到老生代(称为晋升)。

Scavenge算法(用于新生代)
  • 将新生代内存分为两个区域:From 空间To 空间
  • 活跃对象从 From 空间复制到 To 空间。
  • 清空 From 空间,交换 From 和 To 空间角色。

(3) 引用计数算法(Reference Counting)

这是另一种垃圾回收方法,通过跟踪对象的引用次数来判断对象是否可以被回收。

工作原理
  • 每个对象维护一个“引用计数”。
  • 当有新的引用指向对象时,计数 +1。
  • 当引用被移除时,计数 -1。
  • 如果计数为 0,回收该对象。
缺点
  • 无法处理循环引用
    let a = {};
    let b = {};
    a.ref = b;
    b.ref = a;
    // 两者引用计数都不为 0,但实际上已无法访问。
    

由于这个问题,JavaScript 已很少使用引用计数,而采用更强大的标记-清除算法。


3. 垃圾回收的优化机制

(1) 增量回收(Incremental GC)

为了减少标记-清除算法中的全局暂停,增量回收将垃圾回收的过程拆分为多个小步骤,逐步完成垃圾回收。

(2) 并发回收(Concurrent GC)

垃圾回收操作与主线程的代码执行并发进行,进一步减少停顿时间。

(3) 增量标记(Incremental Marking)

在标记阶段分多次完成扫描,避免一次性暂停程序执行。


4. JavaScript 垃圾回收中的 V8 引擎实现

V8 引擎采用了分代垃圾回收机制,结合了标记-清除和增量回收策略:

  1. 新生代垃圾回收(Scavenge)

    • 小对象存活时间短,快速回收。
    • 复制存活对象,清空其余内存。
  2. 老生代垃圾回收(Mark-and-Sweep / Mark-and-Compact)

    • 使用标记-清除算法,定期整理内存以减少碎片。

5. 代码实践中的影响

避免内存泄漏的常见情况
  • 未清理的全局变量
    window.globalVar = "I'm here forever";
    
  • 闭包引用
    function outer() {
      let obj = { key: "value" };
      return function inner() {
        console.log(obj);
      };
    }
    let closure = outer();
    // obj 将一直被引用,不会被回收。
    
  • 事件监听未移除
    const element = document.getElementById("button");
    element.addEventListener("click", () => {
      console.log("Clicked");
    });
    // 如果 element 被移除但事件监听器未清理,内存无法释放。
    
优化内存使用的建议
  1. 尽量避免创建不必要的全局变量。
  2. 使用 WeakMapWeakSet 存储可能被销毁的对象引用。
  3. 确保手动移除事件监听器和 DOM 节点引用。

总结来说,垃圾回收机制极大简化了 JavaScript 的内存管理,但了解其原理和局限性有助于编写更高效和稳定的代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/923334.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Easyexcel(6-单元格合并)

相关文章链接 Easyexcel(1-注解使用)Easyexcel(2-文件读取)Easyexcel(3-文件导出)Easyexcel(4-模板文件)Easyexcel(5-自定义列宽)Easyexcel(6-单…

【GAMES101笔记速查——Lecture 19 Cameras,Lenses and Light Fields】

本章节内容:相机、棱镜、光场 计算机图形学的两种成像方法: 1.合成方法:光栅化、光线追踪(展示出现实没有的东西) 2.捕捉方法:相机(捕捉现实已有的东西) 目录 1 相机 1.1 针孔相…

【Linux】认识进程以及进程的状态

目录 认识进程 基本概念 查看进程 父子进程 进程的状态 进程排队 运行状态 阻塞状态 挂起状态 僵尸进程 孤儿进程 认识进程 基本概念 有些教材上会说:正在运行的程序就是进程。这并没有错误,但是太过于笼统。现在我们深入到Linux底层来了解…

vue3项目部署在阿里云轻量应用服务器上

文章目录 概要整体部署流程技术细节小结 概要 vue3前端项目部署在阿里云轻量服务器 整体部署流程 首先有一个Vue3前端项目和阿里云应用服务器 确保环境准备 如果是新的服务器,在服务器内运行以下命令更新软件包 sudo apt update && sudo apt upgrade -y …

STM32H7开发笔记(2)——H7外设之多路定时器中断

STM32H7开发笔记(2)——H7外设之多路定时器中断 文章目录 STM32H7开发笔记(2)——H7外设之多路定时器中断0.引言1.CubeMX配置2.软件编写 0.引言 本文PC端采用Win11STM32CubeMX4.1.0.0Keil5.24.2的配置,硬件使用STM32H…

Web3 游戏周报(11.17 - 11.23)

回顾上周的区块链游戏概况,查看 Footprint Analytics 与 ABGA 最新发布的数据报告。 【11.17 - 11.23】Web3 游戏行业动态: 加密游戏开发商 Gunzilla Games 发推表示,其已与 Coinbase Ventures 达成合作并获得其投资。 国际足联将与 Mythica…

问题记录-Java后端

问题记录 目录 问题记录1.多数据源使用事务注意事项?2.mybatis执行MySQL的存储过程?3.springBoot加载不到nacos配置中心的配置问题4.服务器产生大量close_wait情况 1.多数据源使用事务注意事项? 问题:在springBoot项目中多表处理数…

微软Ignite 2024:建立一个Agentic世界!

在今年的Microsoft Ignite 2024上,AI Agent无疑成为本次大会的重点,已经有十万家企业通过Copilot Studio创建智能体了。微软更是宣布:企业可以在智能体中,使用Azure目录中1800个LLM中的任何一个模型了! 建立一个Agent…

python画图|无坐标轴自由划线操作fig.add_artist(lines.Line2D()函数

【1】引言 新发现了一种自由划线操作函数,和大家共享。 【2】官网教程 点击下述代码,直达官网: https://matplotlib.org/stable/gallery/misc/fig_x.html#sphx-glr-gallery-misc-fig-x-py 官网代码非常简洁,我进行了解读。 …

基于微信小程序的空巢老人健康管理系统

摘 要 随着社会老龄化程度不断加深,空巢老人的健康管理成为一个日益重要的问题。为了更好地关注和管理空巢老人的健康状况,本文利用Spring Boot框架和MySQL数据库,结合微信小程序等技术,设计并实现了一套基于微信小程序的空巢老人…

【JavaEE】Servlet:表白墙

文章目录 一、前端二、前置知识三、代码1、后端2、前端3、总结 四、存入数据库1、引入 mysql 的依赖&#xff0c;mysql 驱动包2、创建数据库数据表3、调整上述后端代码3.1 封装数据库操作&#xff0c;和数据库建立连接3.2 调整后端代码 一、前端 <!DOCTYPE html> <ht…

小程序-使用 iconfont 图标库报错:Failed to load font

官方默认可以忽略此错误&#xff0c;在清除缓存后首次刷新会显示此错误&#xff0c;重新渲染错误消失 解决方法&#xff1a; 在 iconfont 图标库选择项目设置 选中 Base64 保存&#xff0c;重新点击链接 -> 复制代码到项目中 操作步骤&#xff1a;

用CAXA CAD电子图板导入图框、标题栏并导出pdf的方法

1.导入图框&#xff1a; 点击调入图框->出现读入图框文件 一个一个点击&#xff0c;选择合适的图框 然后点击导入 2.导入标题栏&#xff1a; 调入标题栏->出现读入标题栏文件 一个一个点击&#xff0c;选择合适的标题栏&#xff0c;然后点击导入 3.导出pdf&#x…

《Shader入门精要》透明效果

代码以及实例图可以看github &#xff1a;zaizai77/Shader-Learn: 实现一些书里讲到的shader 在实时渲染中要实现透明效果&#xff0c;通常会在渲染模型时控制它的透明通道&#xff08;Alpha Channel&#xff09;​。当开启透明混合后&#xff0c;当一个物体被渲染到屏幕上时&…

加速科技精彩亮相中国国际半导体博览会IC China 2024

11月18日—20日&#xff0c;第二十一届中国国际半导体博览会&#xff08;IC China 2024&#xff09;在北京国家会议中心顺利举办&#xff0c;加速科技携重磅产品及全系测试解决方案精彩亮相&#xff0c;加速科技创始人兼董事长邬刚受邀在先进封装创新发展论坛与半导体产业前沿与…

【JavaEE初阶 — 多线程】线程池

目录 1. 线程池的原理 1.1 为什么要有线程池 1.2 线程池的构造方法 1.3 线程池的核心参数 1.4 TimeUnit 1.5 工作队列的类型 1.6 工厂设计模式 1.6.1 工厂模式概念 1.6.2 使用工厂模式的好处 1.6.3 使用工厂模式的典型案例 1.6.4 Thread…

JSON 性能测试 - WastJson 性能也很快

WAST 是一个高性能 Java 工具集库包&#xff0c;包括 JSON、YAML、CSV、HttpClient、JDBC 和 EL 引擎. WastJson 无论是小中大文本各种数据类型等性能都没有明显的短板&#xff0c;除了推广外可以说是六边形战士&#xff0c;更多测试参考 wast-jmh-test: wast性能测试 (并非所…

数据库-基础理论

文章目录 前言一、ORM框架二、ACID原则三、事务Transaction四、N1问题五、Normalization三范式六、FMEA方法论&#xff08;Failure Mode and Effects Analysis&#xff09;七、Profiling和PerformanceSchema查询分析 前言 基础理论 ORM框架、ACID原则、事务Transaction、N1问…

AI赋能电商:构建高效、智能化的新零售生态

随着人工智能&#xff08;AI&#xff09;技术的不断进步&#xff0c;其在电商领域的应用日益广泛&#xff0c;从购物推荐到供应链管理&#xff0c;再到商品定价&#xff0c;AI正在全面改变传统电商的运营模式&#xff0c;并推动行业向智能化和精细化方向发展。本文将探讨如何利…

[极客大挑战 2019]BabySQL--详细解析

信息搜集 进入界面&#xff1a; 输入用户名为admin&#xff0c;密码随便输一个&#xff1a; 发现是GET传参&#xff0c;有username和password两个传参点。 我们测试一下password点位能不能注入&#xff1a; 单引号闭合报错&#xff0c;根据报错信息&#xff0c;我们可以判断…