JavaScript垃圾回收机制详解

news2024/11/28 17:37:25

文章目录

      • JavaScript垃圾回收机制详解及代码案例
        • 一、垃圾回收机制概述
        • 二、标记-清除算法(Mark-and-Sweep)
        • 三、引用计数算法(Reference Counting)
        • 四、现代JavaScript引擎的垃圾回收优化
        • 五、常见内存泄漏及避免方法

JavaScript垃圾回收机制详解及代码案例

JavaScript(简称JS)作为前端开发的核心语言,其内存管理机制对于性能优化和避免内存泄漏至关重要。JS中的垃圾回收机制(Garbage Collection, GC)是自动管理内存分配和释放的过程,主要依赖于两种策略:标记-清除(Mark-and-Sweep)和引用计数(Reference Counting)。本文将详细介绍这两种机制,并通过代码案例进行解释。

一、垃圾回收机制概述

垃圾回收机制的目标是自动识别和回收不再被使用的内存,以防止内存泄漏。在JS中,变量和对象的生命周期包括声明、赋值、使用和释放四个阶段。当变量或对象不再被使用时,垃圾回收机制会将其占用的内存释放。

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

原理

  1. 标记阶段:从根对象(全局变量、当前执行上下文中的变量等)出发,遍历所有可达的对象,并将它们标记为“活动”的。
  2. 清除阶段:遍历堆内存,未被标记的对象被认为是垃圾,可以被回收。

优点

  • 实现简单,能够解决循环引用的问题。

缺点

  • 垃圾回收时可能导致内存碎片化,影响内存分配效率。

代码案例

// 创建一个对象,分配内存
let obj = { data: "Hello" };

// 增加一个引用,引用计数(假设存在)为2(实际现代JS引擎不依赖引用计数)
let ref = obj;

// 解除一个引用,但因为ref还存在,所以对象不会被回收
obj = null;

// 现在引用计数(假设存在)为0,理论上在引用计数策略下可以回收
// 实际上,现代JavaScript引擎会采用标记-清除
ref = null;

// 垃圾回收机制会在适当的时候回收obj占用的内存
三、引用计数算法(Reference Counting)

原理

每个对象都有一个引用计数,每当有新的引用指向它时计数加1,引用消失时减1。当计数降为0时,对象被视为垃圾可回收。

优点

  • 能够立即回收垃圾,减少内存占用。

缺点

  • 无法解决循环引用的问题。
  • 时间开销大,需要频繁更新引用计数。

代码案例(理论上的引用计数,现代JS引擎不直接使用):

function test() {
    let A = {};
    let B = {};
    A.b = B;
    B.a = A;
    
    // A和B相互引用,引用计数均为2
    // 如果函数结束,理论上A和B应该被回收,但引用计数不会将它们置为0
}

test();

// 实际上,现代JavaScript引擎会通过标记-清除算法处理循环引用
四、现代JavaScript引擎的垃圾回收优化

现代JavaScript引擎如V8(Chrome和Node.js中使用)和SpiderMonkey(Firefox中使用)在标记-清除算法的基础上进行了优化,如增量标记、分代回收等。

分代回收

  • 新生代:存放存活时间较短的对象,采用复制算法进行垃圾回收,以减少内存碎片化。
  • 老生代:存放存活时间较长的对象,采用标记-清除和标记整理算法进行垃圾回收,以优化内存使用。

代码案例(V8引擎的分代回收示例):

// 创建一个对象,它会被分配到新生代
let shortLivedObject = {};

// 在长时间运行的应用中,对象可能会晋升到老生代
function createLongLivedObject() {
    let longLivedObject = {};
    // 模拟长时间存在的对象
    setInterval(() => {
        longLivedObject.data = Math.random();
    }, 1000);
}

createLongLivedObject();

// 垃圾回收机制会根据对象的存活时间自动进行分代回收
五、常见内存泄漏及避免方法

内存泄漏

  • 长时间运行的应用,特别是涉及大量DOM操作、定时器、闭包、事件监听器时,要特别注意避免内存泄漏。

避免方法

  • 及时释放不必要的引用。
  • 避免循环引用。
  • 使用弱引用(如WeakMap和WeakSet)。
  • 定期检查内存使用情况,使用浏览器开发者工具中的内存分析工具(如Chrome DevTools的Memory面板)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

代码美学2:MATLAB制作渐变色

效果: %代码美学:MATLAB制作渐变色 % 创建一个10x10的矩阵来表示热力图的数据 data reshape(1:100, [10, 10]);% 创建热力图 figure; imagesc(data);% 设置颜色映射为“cool” colormap(cool);% 在热力图上添加边框 axis on; grid on;% 设置热力图的颜色…

Android下载出现open failed: EPERM (Operation not permitted)

今天帮忙给同事调一下apk,发现android 自动更新apk,下载apk的时候总是失败,总是卡在 输出流这一步了 于是第一步分析,立马想到权限 但是下载之前的读写内存的权限也都有了 什么android 10高版本的不开启分区存储也用了 android…

使用爬虫时,如何确保数据的准确性?

在数字化时代,数据的准确性对于决策和分析至关重要。本文将探讨如何在使用Python爬虫时确保数据的准确性,并提供代码示例。 1. 数据清洗 数据清洗是确保数据准确性的首要步骤。在爬取数据后,需要对数据进行清洗,去除重复、无效和…

uniapp中使用Mescroll实现下拉刷新与上拉加载项目实战

如何在UniApp中使用Mescroll实现下拉刷新与上拉加载 前言 下拉刷新和上拉加载更多成为了提升用户体验不可或缺的功能。UniApp作为一个跨平台的应用开发框架,支持使用Vue.js语法编写多端(iOS、Android、H5等)应用。Mescroll作为一款专为Vue设…

【接口自动化测试】一文从0到1详解接口测试协议!

接口自动化测试是软件开发过程中重要的环节之一。通过对接口进行测试,可以验证接口的功能和性能,确保系统正常运行。本文将从零开始详细介绍接口测试的协议和规范。 定义接口测试协议 接口测试协议是指用于描述接口测试的规范和约定。它包含了接口的请求…

RAG数据拆分之PDF

引言RAG数据简介PDF解析方法及工具代码实现总结 二、正文内容 引言 本文将介绍如何将RAG数据拆分至PDF格式,并探讨PDF解析的方法和工具,最后提供代码示例。 RAG数据简介 RAG(关系型属性图)是一种用于表示实体及其关系的图数据…

【开源项目】2024最新PHP在线客服系统源码/带预知消息/带搭建教程

简介 随着人工智能技术的飞速发展,AI驱动的在线客服系统已经成为企业提升客户服务质量和效率的重要工具。本文将探讨AI在线客服系统的理论基础,并展示如何使用PHP语言实现一个简单的AI客服系统。源码仓库地址:ym.fzapp.top 在线客服系统的…

WEB攻防-通用漏洞XSS跨站MXSSUXSSFlashXSSPDFXSS

演示案例: UXSS-Edge&CVE-2021-34506 FlashXSS-PHPWind&SWF反编译 PDFXSS-PDF动作添加&文件上传 使用jpexs反编译swf文件 上传后,发给别人带漏洞的分享链接

QSqlTableModel的使用

实例功能 这边使用一个实例显示数据库 demodb 中 employee 数据表的内容,实现编辑、插入、删除的操作,实现数据的排序和记录过滤,还实现 BLOB 类型字段 Photo 中存储照片的显示、导入等操作,运行界面如下图: 在上图中…

适用于学校、医院等低压用电场所的智能安全配电装置

引言 电力,作为一种清洁且高效的能源,极大地促进了现代生活的便捷与舒适。然而,与此同时,因使用不当或维护缺失等问题,漏电、触电事件以及电气火灾频发,对人们的生命安全和财产安全构成了严重威胁&#xf…

LabVIEW实现UDP通信

目录 1、UDP通信原理 2、硬件环境部署 3、云端环境部署 4、UDP通信函数 5、程序架构 6、前面板设计 7、程序框图设计 8、测试验证 本专栏以LabVIEW为开发平台,讲解物联网通信组网原理与开发方法,覆盖RS232、TCP、MQTT、蓝牙、Wi-Fi、NB-IoT等协议。 结合…

java——Spring MVC的工作流程

Spring MVC的工作流程是基于模型-视图-控制器(MVC)设计模式的一个典型实现,以下是其主要工作流程步骤: 客户端请求提交: 用户通过浏览器向服务器发送请求,该请求首先到达Spring MVC的前端控制器DispatcherS…

带有悬浮窗功能的Android应用

android api29 gradle 8.9 要求 布局文件 (floating_window_layout.xml): 增加、删除、关闭按钮默认隐藏。使用“开始”按钮来控制这些按钮的显示和隐藏。 服务类 (FloatingWindowService.kt): 实现“开始”按钮的功能,点击时切换增加、删除、关闭按钮的可见性。处…

【编译原理】词法、语法、语义实验流程内容梳理

编译原理实验有点难,但是加上ai的辅助就会很简单,下面梳理一下代码流程。 全代码在github仓库中,链接:NeiFeiTiii/CompilerOriginTest at Version2.0,感谢star一下 一、项目结构 关键内容就是里面的那几个.c和.h文件。…

Linux介绍与安装指南:从入门到精通

1. Linux简介 1.1 什么是Linux? Linux是一种基于Unix的操作系统,由Linus Torvalds于1991年首次发布。Linux的核心(Kernel)是开源的,允许任何人自由使用、修改和分发。Linux操作系统通常包括Linux内核、GNU工具集、图…

MFC图形函数学习12——位图操作函数

位图即后缀为bmp的图形文件,MFC中有专门的函数处理这种格式的图形文件。这些函数只能处理作为MFC资源的bmp图,没有操作文件的功能,受限较多,一般常作为程序窗口界面图片、显示背景图片等用途。有关位图操作的步骤、相关函数等介绍…

12.Three.js纹理动画与动效墙案例

12.Three.js纹理动画与动效墙案例 在Three.js的数字孪生场景应用中,我们通常会使用到一些动画渲染效果,如动效墙,飞线、雷达等等,今天主要了解一下其中一种动画渲染效果:纹理动画。下面实现以下动效墙效果&#xff08…

SJYP 24冬季系列 FROZEN CHARISMA发布

近日,女装品牌SJYP 2024年冬季系列——FROZEN CHARISMA已正式发布,展现了更加干练的法式风格。此次新品发布不仅延续了SJYP一贯的强烈设计风格和个性时尚,更融入了法式风情的干练元素,为消费者带来了一场视觉与穿着的双重盛宴。  …

无人机产业发展如何?如何进行产业分析?

▶无人机产业发展现状:高速增长 1.市场规模和增长趋势: 全球无人机市场规模在2021年约为256亿美元,同比增长14%。中国民用无人机市场规模在2021年达到869.12亿元,显示出市场的快速增长。 预计到2029年,中国无人机市…

<项目代码>YOLOv8 红绿灯识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…