JS对象循环引用的危害:你知道吗?

在这里插入图片描述

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6
🍨 阿珊和她的猫_CSDN个人主页
🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》
🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》

文章目录

  • 一、引言
    • 循环引用的概念
    • 循环引用的问题
    • 对程序性能的影响
  • 二、JS对象循环引用的示例
  • 三、解决JS对象循环引用的方法
  • 四、避免JS对象循环引用
  • 五、总结

一、引言

循环引用的概念

在JavaScript中,循环引用(circular references)是指在对象之间存在相互引用的情况,形成一个闭环,导致对象无法被完全释放和垃圾回收。循环引用发生在当一个对象的属性或成员引用另一个对象,并且这个被引用的对象又直接或间接地引用回原始对象,从而形成一个循环。

当存在循环引用时,JavaScript的垃圾回收机制可能无法正确地处理这些对象,因为它们之间的引用形成了一个无法访问的闭环,无法确定哪些对象是不再被使用的,这可能导致内存泄漏,即占用的内存无法被回收,最终导致内存资源的浪费和性能问题。

循环引用的问题

在 JavaScript 中,循环引用可能会导致内存泄漏和性能问题。下面是一个简单的例子:

function problem() {var objectA = new Object();var objectB = 12341234;objectA.b = objectB;objectB.a = objectA;
}

在这个例子中,objectAobjectB之间形成了循环引用,导致它们无法被垃圾回收器回收,从而造成内存泄漏。

为了避免循环引用,在使用对象时应该注意避免相互引用,并及时断开循环引用关系。在某些情况下,可以使用垃圾回收器或其他工具来帮助管理内存。

对程序性能的影响

在 JavaScript 中,循环引用会对程序的性能产生负面影响,主要包括以下几个方面:

  1. 内存泄漏:当存在循环引用时, JavaScript 的垃圾回收机制无法正确释放不再使用的内存空间,导致内存泄漏。随着时间的推移,程序可能会消耗大量的内存,从而降低系统的性能。

  2. 性能下降:垃圾回收器在处理循环引用时需要花费更多的时间和资源来遍历和识别这些对象。这可能导致程序的执行速度变慢,特别是在需要频繁创建和销毁对象的情况下。

  3. 意外行为:循环引用可能导致意外的行为,例如对象的属性或方法在预期之外被访问或修改。这可能导致程序出现错误或不稳定的情况。

在这里插入图片描述

为了避免循环引用对程序性能的影响,应该尽量避免在对象之间创建循环引用,并及时断开循环引用关系。在设计和开发代码时,可以使用一些常见的实践方法,例如使用 WeakMap 或WeakSet 来存储弱引用,或者手动释放对象的引用。

二、JS对象循环引用的示例

在 JavaScript 中,对象循环引用是指两个或多个对象之间通过属性相互引用,形成一个循环结构。下面是一个示例代码,展示了对象循环引用的情况:

// 定义两个对象
let obj1 = { data: 1 };
let obj2 = { data: 2 };
// 建立循环引用
obj1.reference = obj2;
obj2.reference = obj1;
console.log(obj1);
console.log(obj2);

在这个示例中,我们创建了两个对象 obj1obj2,并通过 reference 属性建立了它们之间的循环引用关系。

输出结果:

{ data: 1, reference: { data: 2, reference: {…} } }
{ data: 2, reference: { data: 1, reference: {…} } }

说明内存使用情况:

  • 在这个示例中,由于存在对象循环引用,obj1obj2 都无法被垃圾回收器正常释放。
  • 即使我们不再使用这两个对象,它们仍然会占用内存空间,导致内存泄漏。
  • 为了解决这个问题,我们可以手动断开循环引用,或者使用一些工具来检测和处理循环引用的情况,例如使用 WeakMap 或 WeakSet 来存储弱引用。

总之,对象循环引用会导致内存泄漏,应该尽量避免或及时处理。

三、解决JS对象循环引用的方法

在这里插入图片描述

在 JavaScript 中,对象循环引用是指两个或多个对象之间通过属性相互引用,形成一个循环结构,导致这些对象无法被垃圾回收器正确释放,从而引发内存泄漏问题。以下是几种常见的解决对象循环引用的方法和案例:

  1. 使用弱引用(WeakReference):
    弱引用是一种特殊的引用类型,它不会阻止垃圾回收器对对象的回收。在 JavaScript 中,可以使用WeakMap 或 WeakSet 来创建弱引用。下面是一个使用 WeakMap 解决对象循环引用的示例:

    // 定义两个对象
    let obj1 = { data: 1 };
    let obj2 = { data: 2 };// 创建弱引用
    let weakMap = new WeakMap();
    weakMap.set(obj1, obj2);
    weakMap.set(obj2, obj1);// 断开循环引用
    weakMap.delete(obj1);
    weakMap.delete(obj2);console.log(obj1);
    console.log(obj2);
    

    在上面的示例中,我们使用 WeakMap 创建了对象 obj1 和 obj2 之间的弱引用。然后,通过删除弱引用,断开了对象之间的循环引用。这样,当对象不再被其他强引用所引用时,垃圾回收器就可以正确地回收它们,解决了内存泄漏问题。

  2. 使用垃圾回收器:
    JavaScript 的垃圾回收器会定期执行垃圾回收操作,释放不再使用的内存空间。然而,对于对象循环引用的情况,垃圾回收器可能无法正确处理。为了确保对象能够被正确回收,可以手动触发垃圾回收器,例如使用 collectGarbage() 方法或 v8.discardCode() 方法。下面是一个手动触发垃圾回收器的示例:

    // 定义两个对象
    let obj1 = { data: 1 };
    let obj2 = { data: 2 };// 建立循环引用
    obj1.reference = obj2;
    obj2.reference = obj1;// 手动触发垃圾回收器
    collectGarbage();console.log(obj1);
    console.log(obj2);
    

    在上面的示例中,我们手动触发了垃圾回收器,强制执行垃圾回收操作。这样可以确保对象循环引用被正确处理,释放占用的内存空间。

  3. 手动释放资源:
    在某些情况下,可能需要手动释放对象所占用的资源,例如删除事件监听器、释放文件句柄等。下面是一个手动释放事件监听器的示例:

    // 定义两个对象
    let obj1 = { data: 1 };
    let obj2 = { data: 2 };// 建立循环引用
    obj1.reference = obj2;
    obj2.reference = obj1;// 添加事件监听器
    obj1.addEventListener('event', function() {console.log('Event triggered');
    });// 断开循环引用
    obj1.reference = null;
    obj2.reference = null;// 手动删除事件监听器
    obj1.removeEventListener('event', function() {});console.log(obj1);
    console.log(obj2);
    

    在上面的示例中,我们先添加了一个事件监听器到对象 obj1 上。然后,断开了对象之间的循环引用,并手动删除了事件监听器。这样可以确保在对象不再被使用时,释放相关的资源。

需要根据具体的应用场景选择合适的解决方法。在处理对象循环引用时,弱引用和手动触发垃圾回收器通常是比较常见和有效的方式。同时,手动释放资源可以帮助释放其他类型的资源。

请注意,手动管理内存和资源释放需要谨慎操作,避免引入其他问题。在大多数情况下,JavaScript 的垃圾回收机制可以自动处理对象的释放,只有在遇到特殊情况或性能要求较高的场景时,才需要考虑手动干预。

四、避免JS对象循环引用

在 JavaScript 中,对象循环引用是指两个或多个对象之间相互引用,形成一个循环结构,导致垃圾回收器无法正确释放这些对象所占用的内存。为了避免对象循环引用,可以考虑以下几个方面:

  1. 代码设计:

    • 使用良好的编码规范和设计模式,避免创建不必要的对象引用。
    • 尽量保持对象之间的引用关系简单清晰,避免复杂的嵌套引用。
    • 及时断开不再需要的对象引用,例如在函数执行完毕后将局部变量设置为 null 或 undefined。
  2. 内存管理:

    • 使用垃圾回收器:JavaScript 自带垃圾回收机制,会自动管理内存并释放不再使用的对象。尽量依靠垃圾回收器来处理对象的内存释放,避免手动干预。
    • 控制对象的生命周期:合理控制对象的创建和销毁时间,避免长时间持有不必要的对象。
    • 使用作用域链:利用 JavaScript 的作用域链特性,合理管理对象的可见性和生存周期。
    • 避免大量创建临时对象:尽量减少临时对象的创建,尤其是在循环等密集计算操作中。
    • 使用优化工具:借助一些 JavaScript 性能优化工具,如 Profiler 工具,可以帮助分析和检测对象的内存使用情况,找出潜在的循环引用问题。

总的来说,避免对象循环引用需要在代码设计和内存管理方面注意一些最佳实践,保持对象之间的引用关系简单清晰,并合理控制对象的生命周期。如果遇到循环引用问题,可以使用一些调试工具来帮助检测和解决。

五、总结

  1. JS 对象循环引用的危害: 对象循环引用会导致内存泄漏,使得 JavaScript 的垃圾回收机制无法正确释放不再使用的对象,从而浪费内存资源。

  2. 解决 JS 对象循环引用的方法: 可以使用弱引用(WeakMapWeakSet)来建立对象之间的关系,或者手动触发垃圾回收器(collectGarbage())来处理循环引用问题。

  3. 避免 JS 对象循环引用的建议: 遵循良好的代码设计规范和内存管理原则,尽量保持对象之间的引用关系简单清晰,及时断开不再需要的对象引用,控制对象的生命周期,避免大量创建临时对象。合理使用作用域链,减少临时对象的创建。借助一些 JavaScript 性能优化工具,如 Profiler 工具,可以帮助分析和检测对象的内存使用情况,找出潜在的循环引用问题。

总之,通过良好的代码设计和内存管理,可以有效避免 JavaScript 对象循环引用问题的发生。

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

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

相关文章

移动端机器学习框架 MDL 简介与实践

Mobile-deep-learning(MDL) MDL 是百度研发的可以部署在移动端的基于卷积神经网络实现的移动端框架,可以应用在图像识别领域。 具体应用:在手机百度 App 中,用户只需要点击自动拍开关,将手机对准物体&…

联想王传东:AI PC迈入AI Ready 即将开启AI On

“AI PC已经正式迈入AI Ready 阶段,接下来会逐渐进入到AI On阶段。”12月16日,英特尔人工智能创新应用大赛启动仪式在深圳举办。作为独家AI PC合作伙伴,联想集团副总裁、中国区首席市场官王传东代表公司出席仪式并致辞。 王传东认为AI PC的发…

大模型Transformer 推理 :kvCache原理浅析

大模型Transformer 推理 :kvCache原理浅析 kvCache 原理 在采样时,Transformer模型会以给定的提示/上下文作为初始输入进行推理(可以并行处理),然后逐一生成额外的标记来继续完善生成的序列(体现了模型的自回归性质)。在采样过程中,Transformer会执行自注意力操作,为…

27系列DGUS智能屏发布:可实时播放高清模拟信号摄像头视频

针对高清晰度的模拟信号摄像头视频画面的显示需求,迪文特推出27系列DGUS智能屏。该系列智能屏可适配常见的AHD摄像头、CVBS摄像头,支持单路1080P高清显示、两路720P同屏显示(同一类型摄像头)。用户通过DGUS简单开发即可实现摄像头…

【送书活动】智能汽车、自动驾驶、车联网的发展趋势和关键技术

文章目录 前言01 《智能汽车》推荐语 02 《SoC底层软件低功耗系统设计与实现》推荐语 03 《SoC设计指南》推荐语 05 《智能汽车网络安全权威指南(上册)》推荐语 06 《智能汽车网络安全权威指南(下册)》推荐语 后记赠书活动 前言 …

mac安装pnpm与使用

1、什么是pnpm? pnpm 全称 performant npm,意思是高性能的 npm。pnpm 由 npm/yarn 衍生而来,解决了 npm/yarn 内部潜在的 bug,极大的优化了性能,扩展了使用场景。被誉为 “最先进的包管理工具”。 2、pnpm特点 速度…

虚拟机启动 I/O error in “xfs_read_agi+0x95“

1.在选择系统界面按e 进入维护模式 2.找到ro把ro改成 rw init/sysroot/bin/sh 然后按Ctrlx 3.找到坏掉的分区,以nvme0n1p3为例进行修复 xfs_repair -d /dev/nvme0n1p3 4.init 6 重新启动 以下情况 先umount 再修复 则修复成功

接口测试 — 4.Requests库GET、Post请求

Requests库GET请求是使用HTTP协议中的GET请求方式对目标网站发起请求。 (不带参数的GET请求请看上一篇文章的练习) 1、Requests库待参数的GET请求 使用Get方法带参数请求时,是params参数字典,而不是data参数字典。data参数字典…

dcoker-compose一键部署EFAK —— 筑梦之路

简介 EFAK(Eagle For Apache Kafka,以前称为 Kafka Eagle)是一款由国内公司开源的Kafka集群监控系统,可以用来监视kafka集群的broker状态、Topic信息、IO、内存、consumer线程、偏移量等信息,并进行可视化图表展示。独…

Arduino中以太网Udp通信

目录 1、测试硬件 2、程序 (0)头文件添加 (1)变量定义 (2)初始化程序 (3)循环执行程序 3、程序下载 (1)开发板控制器和端口号选择 (2&am…

pycharm某个xxx.sh文件显示问号,无法编辑

文章目录 pycharm某个xxx.sh文件显示问号,无法编辑其他参考 pycharm某个xxx.sh文件显示问号,无法编辑 问题描述:pycharm某个xxx.sh文件显示问号,无法编辑 问题分析: pycharm无法识别文件类型。 问题解决: 在pycharm中选中该文件&#xff0…

BugKu-Web-滑稽

题目环境 持续的动态图片 F12审查元素 拿下flag:flag{595d994a34342417bfc3a3c3a23e0a48}

synchronized关键字的使用和原理

synchronized关键字的使用和原理 synchronized:对象锁,保证了临界区内代码的原子性,采用互斥的方式让同一时刻至多只有一个线程能持有对象锁,其它线程获取这个对象锁时会阻塞,保证拥有锁的线程可以安全的执行临界区内…

【Android】MVC与MVP的区别,MVP网络请求实践

一、MVC模式 目录 一、MVC模式二、MVP模式 1、MVP的简单应用 1.1 导入相关依赖包并设置权限1.2 实现Model1.2 实现Presenter1.3 实现View1.4分析项目结构和绑定过程1.5效果展示 2、MVP结合RxJava 一、MVC模式 MVC(Model(模型)——View(视图)——Controller(控制…

设计模式-状态(State)模式

目录 开发过程中的一些场景 状态模式的简单介绍 状态模式UML类图 类图讲解 适用场景 Java中的例子 案例讲解 什么是状态机 如何实现状态机 SpringBoot状态自动机 优点 缺点 与其他模式的区别 小结 开发过程中的一些场景 我们在平时的开发过程中,经常会…

【Android】在Android上使用mlKit构建人脸检测程序

在Android上构建人脸检测程序 目录 1、导入mlKit依赖包2、配置人脸检测器并且获取人脸检测器3、加载图片资源4、调用人脸检测器5、绘制矩形边框6、完整代码7、效果展示 1、导入mlKit依赖包 dependencies {// ...// Use this dependency to bundle the model with your appi…

CSS盒子的浮动与网页布局(重点,有电影页面案例)

浮动适用于那种盒子的并列布局 CSS 提供了三种传统布局方式(简单说,就是盒子如何进行排列顺序):  普通流(标准流)  浮动  定位 标准流(普通流/文档流) 所谓的标准流: 就是标签按照规定好默认方式排列. 1. 块级…

abap 如何debug 更新进程

今天在测试环境做一个外向交货单过账的时候,每次都会dump ST22中看到报错如下:DBSQL_DUPLICATE_KEY_ERROR 接着我就去SM13去看下在哪个跟新里面失败了 双击错误条目可以看到 那么我就想说去debug看看当时的变量到底是啥,为啥会主键重复&…

数据库的三大范式

第一范式: 属性不可分割:每个属性都是不可分割的原子项(实体的属性就是表中的列) 在上表中contact应该分为phone和adress两列 第二范式: 在满足第一范式的情况下,表中不存在部分依赖,非主键列…

压缩包文件暴力破解 -Server2005(解析)

任务五十一: 压缩包文件暴力破解 任务环境说明:Server2005 1. 通过本地PC中渗透测试平台Kali使用Nmap扫描目标靶机服务版本信息,将 Telnet 版本信息字符串 作为 Flag 提交; flag:Microsoft Windows XP telnetd 2. 通过本地PC中渗透测试平台Kali对服务器场景Windows进行渗透测…