WeakMap 和 WeakSet:解决内存泄漏避免循环引用(下)

在这里插入图片描述

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

文章目录

  • 四、 WeakMap 和 WeakSet 的应用场景
    • 解决内存泄漏问题
    • 避免循环引用
    • 临时数据存储
    • 缓存
  • 五、 WeakMap 和 WeakSet 的优缺点
    • 优点
    • 缺点
  • 六、总结
    • 回顾 WeakMap 和 WeakSet 的重要概念和特点
    • 强调它们在处理内存泄漏和避免循环引用方面的优势

四、 WeakMap 和 WeakSet 的应用场景

在这里插入图片描述

以下是使用代码案例详细说明 WeakMap 和 WeakSet 的应用场景:

解决内存泄漏问题

内存泄漏是指程序中不再使用的对象仍然保留在内存中,导致内存占用过高,甚至可能导致程序崩溃。WeakMap 可以用来解决这个问题,因为它的键是弱引用的,当键不再被其他对象引用时,WeakMap 会自动释放对应的键值对,从而避免内存泄漏。

// 示例:使用 WeakMap 解决内存泄漏问题
class LeakyClass {constructor() {this.data = new Map();}// 添加数据setData(key, value) {this.data.set(key, value);}// 获取数据getData(key) {return this.data.get(key);}// 移除数据removeData(key) {this.data.delete(key);}
}// 创建 LeakyClass 的实例
const leakyObject = new LeakyClass();// 将对象添加到 WeakMap 中,并将其作为键
const weakMap = new WeakMap();
weakMap.set(leakyObject, 'some data');// 断开对 leakyObject 的引用
leakyObject = null;// 检查 WeakMap 中是否仍然存在对应键值对
console.log(weakMap.has(leakyObject)); 

在上述示例中,我们创建了一个LeakyClass类,它有一个data属性,用于存储数据。我们将leakyObject添加到weakMap中,并将其作为键。然后,我们断开对leakyObject的引用,此时leakyObject成为垃圾回收的候选对象。最后,我们检查weakMap中是否仍然存在对应键值对。由于leakyObject已经不再被引用,它将被垃圾回收,因此weakMap.has(leakyObject)返回false

避免循环引用

循环引用是指两个或多个对象之间相互引用,形成一个循环,导致这些对象无法被垃圾回收。WeakSet 可以用来避免循环引用,因为它的成员是弱引用的,不会阻止垃圾回收。

// 示例:使用 WeakSet 避免循环引用
class Node {constructor(value) {this.value = value;this.children = new WeakSet();}addChild(node) {this.children.add(node);}removeChild(node) {this.children.delete(node);}
}// 创建两个 Node 对象,并形成循环引用
const node1 = new Node(1);
const node2 = new Node(2);
node1.addChild(node2);
node2.addChild(node1);// 将 node1 添加到 WeakSet 中
const weakSet = new WeakSet();
weakSet.add(node1);// 断开对 node1 的引用
node1 = null;// 等待垃圾回收
setTimeout(() => {// 检查 WeakSet 中是否仍然存在 node1console.log(weakSet.has(node1)); 
}, 1000);

在上述示例中,我们创建了两个Node对象,并通过addChild方法形成循环引用。然后,我们将node1添加到weakSet中。最后,我们断开对node1的引用,并等待垃圾回收。在垃圾回收之后,weakSet.has(node1)返回false,因为node1已经被回收。

临时数据存储

WeakMap 和 WeakSet 可以用于存储临时数据,这些数据只在特定的时间段内有用。由于它们的弱引用特性,当不再需要这些数据时,它们会被自动释放,不会造成内存泄漏。

// 示例:使用 WeakMap 存储临时数据
const weakMap = new WeakMap();// 创建一个临时对象,并将其添加到 WeakMap 中
const tempObject = {key: 'value'};
weakMap.set(tempObject, 'some data');// 使用临时对象
console.log(weakMap.get(tempObject)); // 断开对临时对象的引用
tempObject = null;// 等待垃圾回收
setTimeout(() => {// 检查 WeakMap 中是否仍然存在对应键值对console.log(weakMap.has(tempObject)); 
}, 1000);

在上述示例中,我们使用WeakMap存储了一个临时对象和相关的数据。然后,我们断开对临时对象的引用,并等待垃圾回收。最后,WeakMap.has(tempObject)返回false,因为临时对象已经被回收。

缓存

WeakMap 和 WeakSet 也可以用于缓存数据,尤其是在一些数据可能会变得很大的情况下。由于它们的弱引用特性,可以确保在不再需要这些数据时,它们会被自动释放,避免占用过多的内存。

// 示例:使用 WeakMap 进行缓存
const weakMap = new WeakMap();// 创建一个大型对象,并将其添加到 WeakMap 中
const largeObject = {key: 'value'};
weakMap.set(largeObject, 'cached data');// 使用缓存的数据
console.log(weakMap.get(largeObject)); // 断开对大型对象的引用
largeObject = null;// 等待垃圾回收
setTimeout(() => {// 检查 WeakMap 中是否仍然存在对应键值对console.log(weakMap.has(largeObject)); 
}, 1000);

在上述示例中,我们使用WeakMap缓存了一个大型对象。然后,我们断开对大型对象的引用,并等待垃圾回收。最后,WeakMap.has(largeObject)返回false,因为大型对象已经被回收。

这些只是 WeakMap 和 WeakSet 的一些常见应用场景。实际使用中,具体的场景可能会有所不同,需要根据具体情况选择合适的数据结构来解决问题。

五、 WeakMap 和 WeakSet 的优缺点

优点

  • 减少内存泄漏
  • 自动释放不再需要的对象
  • 提高性能

缺点

  • 不支持遍历
  • 键必须是对象

在这里插入图片描述

六、总结

回顾 WeakMap 和 WeakSet 的重要概念和特点

WeakMap 和 WeakSet 是ES6提供的新的数据结构,它们的特点和概念如下:

  • WeakMap:类似于Map,但是键只能是对象类型,且键名所指向的对象是弱引用这意味着如果这个对象在其他地方没有被引用,那么它将会被垃圾回收,这也是WeakMap的主要应用场景。
  • WeakSet:类似于Set,但成员只能是对象类型,且成员对象是弱引用这意味着如果这个对象在其他地方没有被引用,那么它将会被垃圾回收,这也是WeakSet的主要应用场景。

需要注意的是,WeakMap 和 WeakSet 的键是弱引用,这意味着垃圾回收机制可以自动回收不再被引用的键所对应的对象,而不用手动删除键或者值。

强调它们在处理内存泄漏和避免循环引用方面的优势

WeakMap 和 WeakSet 在处理内存泄漏和避免循环引用方面具有以下优势:

  1. 内存泄漏:WeakMap 和 WeakSet 的键是弱引用,这意味着如果一个对象不再被其他地方引用,那么它所对应的键也将不再被 WeakMap 或 WeakSet 引用,从而可以被垃圾回收器回收,避免了内存泄漏的问题

  2. 避免循环引用:循环引用是指两个或多个对象相互引用,导致它们无法被垃圾回收器回收。WeakMap 和 WeakSet 的弱引用特性可以帮助避免循环引用的问题,因为它们不会阻止垃圾回收器回收其他对象

  3. 性能优势:由于 WeakMap 和 WeakSet 的键是弱引用,它们不会对对象的生存时间产生影响,因此在某些情况下可以提高性能,尤其是在处理大量对象时。

总之,WeakMap 和 WeakSet 在处理内存泄漏和避免循环引用方面具有优势,可以帮助开发人员更好地管理内存和避免潜在的问题。

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

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

相关文章

Debian在升级过程中报错

当我们在升级的过程中出现如下报错信息 报错信息如下所示: The following signatures couldnt be verified because the public key is not available: NO_PUBKEY ED444FF07D8D0BF6 W: GPG error: http://mirrors.jevincanders.net/kali kali-rolling InRelease: …

版本化数据库管理工具Flyway介绍和Spring Boot集成使用

文章目录 核心功能如何使用 Flyway最佳实践Spring Boot使用 Flyway 是一个版本化数据库管理工具,用于跟踪、管理和应用数据库的变化。它非常适合在团队开发环境中使用,其中多个人员可能会在数据库结构进行更改。Flyway 通过版本控制可以帮助你确保所有人…

用户管理第2节课-idea 2023.2 后端一删除表,从零开始---【本人】

一、清空model文件夹下,所有文件 1.1.1效果如下: 1.1代码内容 package com.daisy.usercenter.model;import lombok.Data;Data public class User {private Long id;private String name;private Integer age;private String email; }二、清空mapper文件…

Ajax Search Pro Live WordPress网站内容实时搜索插件

点击阅读Ajax Search Pro Live WordPress网站内容实时搜索插件原文 Ajax Search Pro Live WordPress网站内容实时搜索插件是 WordPress 最好的实时搜索引擎插件。高度可定制,具有许多功能和选项,可提供最佳结果!用更美观、更高效的搜索引擎替…

STM32 使用ARM仿真器设置

STM32单片机程序下载到单片机芯片中有两种方式,①编译生成HEX,使用程序烧录软件刷到单片机芯片里。②使用ARM仿真器下载程序。使用ARM仿真器的优势是,在工程编译没问题直接在Keil软件里就可以将程序下载到单片机里,并且程序可以在…

代码随想录刷题题Day19

刷题的第十九天,希望自己能够不断坚持下去,迎来蜕变。😀😀😀 刷题语言:C Day19 任务 ● 669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树 1 修剪二叉搜索树 669…

华为全屋wifi6蜂鸟套装标准

华为政企42 华为政企 目录 上一篇华为安防监控摄像头下一篇华为企业级无线路由器

three.js实战模拟VR全景视图

文章中使用到的案例图片都来源于&#xff1a;Humus - Textures 里面有很多免费的资源&#xff0c;可以直接下载&#xff0c;每个资源里面都提供6个不同方位的图片&#xff0c;我们通过threejs稍微处理一下&#xff0c;就能实现以下3D效果的场景了。 <template><div …

基于多反应堆的高并发服务器【C/C++/Reactor】(上)

&#xff08;一&#xff09;初始化服务器端用于监听的套接字 Server.h #pragma once // 初始化监听的套接字 int initListenFd(unsigned short port); Server.c int initListenFd(unsigned short port) {// 1.创建监听的fdint lfd socket(AF_INET, SOCK_STREAM, 0);if(lf…

C语言数据结构-----常用七种排序介绍、分类、实现及性能比较

前言 ①排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 ②稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&#xff0c;若经过排序&#…

模型实战(18)之C++ - tensorRT部署GAN模型实现人脸超分辨重建

模型实战(18)之C++ - tensorRT部署GAN模型实现人脸超分辨重建 一个实现人脸超分辨率重建的demo支持StyleGAN: GPEN or GFPGAN通过C++ - tensorrt 快速部署,推理速度每帧 在RTX3090上5.5ms+,RTX3050上10ms+下边是实现效果(图片来源于网络search,如若侵权,联系删除) 下边…

R语言【cli】——cli_warn可以更便捷的在控制台输出警告信息

Package cli version 3.6.2 cli_warn(message, ..., .envir parent.frame()) 参数【message】&#xff1a;它是通过调用 cli_bullets() 进行格式化的。进一步地&#xff0c;还需要调用 inline-makeup&#xff08;内联标记&#xff09;。 参数【...】&#xff1a;传递给 rlan…

Spring Boot集成RocketMQ之消息对象序列化

以下源码基于rocketmq-spring-boot-start 2.1.1版本&#xff0c;其它版本可能会有差异 一. 前言 当我们在Spring Boot项目中集成RocketMQ后&#xff0c;只需要在配置文件(application.yml)中添加rocketmq的相关配置&#xff0c;即可使用rocketMQTemplate发送对象消息。登录Ro…

【深入解析spring cloud gateway】12 gateway参数调优与分析

本节主要对网关主要的一些参数做一些解释说明&#xff0c;并用压测工具测试一下网关的接口&#xff0c;通过压测来验证参数配置是否合理 一、连接池参数 参数示例 spring:application:name: gatewaycloud:gateway:# http连接设置httpclient:# 全局的响应超时时间&#xff0c…

AIGC绘画关键词 - 动物类(一)

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

计算机网络实验速成

目录 网络实验速成 自动连接类型&#xff1a; 指示灯状态说明&#xff1a; 显示接口&#xff1a; 放置注释信息&#xff1a; 配置计算机&#xff1a; 同理&#xff0c;配置服务器&#xff1a; 配置路由器&#xff1a; router0 配置&#xff1a; router1 配置&…

109基于MATLAB 中的设施布局设计和位置分配

基于MATLAB 中的设施布局设计和位置分配&#xff0c;通过PSO算法进行最佳位置匹配。程序已调通&#xff0c;可直接运行。 109设施布局设计和位置分配通 (xiaohongshu.com)

云原生系列3-Kubernetes

1、Kubernetes概述 k8s缩写是因为k和s之间有八个字符。k8s是基于容器技术的分布式架构方案。官网&#xff1a;https://kubernetes.io/zh-cn/ Google在 2014年开源了Kubernetes项目&#xff0c;Kubernetes是一个用于自动化部署、扩展和管理容器化应用程序的开源系统。同样类似的…

Polygon zkEVM Spearbit审计报告解读(2022年12月版本)

1. 引言 前序博客&#xff1a; Polygon zkEVM Hexens审计报告解读&#xff08;2022年12月至2023年2月版本&#xff09; 主要见&#xff1a; Polygon zkEVM Security Review: December 2022 Engagement Polygon zkEVM为提供&#xff08;opcode层面兼容的&#xff09;EVM等价…

隐藏通信隧道技术——防御DNS隧道攻击

隐藏通信隧道技术——防御DNS隧道攻击 DNS协议 ​ DNS协议是一种请求/应答协议&#xff0c;也是一种可用于应用层的隧道技术。虽然激增的DNS流量可能会被发现&#xff0c;但是基于传统Socket隧道已经濒临淘汰及TCP、UDP通信大量被防御系统拦截的状况&#xff0c;DNS、ICMP、H…