首页 > 系统相关 >weakmap、weakset、内存泄漏

weakmap、weakset、内存泄漏

时间:2024-10-16 23:47:45浏览次数:3  
标签:对象 引用 WeakMap 回收 weakmap 内存 weakset WeakSet

weakmap、weakset都是ES6的新增的数据结构

WeakMap

WeakMap 对象是键值对的集合,提供了一种键值对的存储机制。它的键必须是对象类型,值可以是任意类型。它的键被弱保持,也就是说,当其键所指对象没有其他地方引用的时候,它会被 GC 回收掉。WeakMap 提供的接口与 Map 相同。

Map 对象不同的是 :

  • WeakMap 的键是不可枚举的。不提供列出其键的方法。列表是否存在取决于垃圾回收器的状态,是不可预知的。

基本特性

  1. 键的类型限制:WeakMap的键只能是对象类型(如Object、Array等),不能是原始数据类型(如Number、String、Symbol等)。这是因为弱引用的概念只适用于对象。

  2. 不可枚举性:WeakMap中的键不能被枚举、迭代或获取数量。这意味着不能使用for...of循环、forEach方法或keys()、values()、entries()等方法来遍历WeakMap。

主要方法

  1. set(key, value):添加

  2. get(key):根据给定的键(必须是一个对象)获取对应的值。如果键不存在于WeakMap中,则返回undefined。

  3. has(key):检查WeakMap中是否存在给定的键(必须是一个对象)。如果存在,则返回true;否则返回false。

不提供clear size (为了提供一种不会干扰垃圾回收机制的键值对存储方式,因此不需要手动清理或获取键值对的数量。)

应用场景

  1. 存储临时对象:WeakSet非常适合用于存储那些在程序的后续运行中可能不再被使用的临时对象。由于WeakSet中的对象是弱引用的,它们在不再被其他地方引用时,会被垃圾回收机制及时回收。

  2. 避免内存泄漏:在前端开发中,WeakSet可以用于存储DOM节点等可能会被移除的对象。当这些节点从文档中移除时,由于WeakSet的弱引用特性,它们所占用的内存可以被垃圾回收机制自动回收,从而避免内存泄漏。

示例

// 创建一个WeakMap实例  
const weakMap = new WeakMap();  

 可参考

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/WeakMap

WeakSet  

WeakSet 对象是一些对象值的集合, 并且其中的每个对象值都只能出现一次。在 WeakSet 的集合中是唯一的

它和 Set 对象的区别有两点:

  • Set 相比,WeakSet 只能是对象的集合,而不能是任何类型的任意值。

  • WeakSet 持弱引用:集合中对象的引用为弱引用。 如果没有其他的对 WeakSet 中对象的引用,那么这些对象会被当成垃圾回收掉。 这也意味着 WeakSet 中没有存储当前对象的列表。 正因为这样,WeakSet 是不可枚举的。

基本特性

  1. 对象成员:WeakSet中的成员只能是对象,不允许其他类型的值(如原始数据类型Number、String、Symbol等)作为成员。

  2. 弱引用:WeakSet中的对象是弱引用的,这意味着如果对象在WeakSet之外没有其他强引用,那么垃圾回收机制可以自动释放它所占用的内存。这一特性有助于避免内存泄漏,因为当对象不再被需要时,垃圾回收机制可以自动回收它,而不会因为WeakSet的引用而阻止回收。

  3. 不可遍历

主要方法

  1. add(value):增加

  2. delete(value):删除

  3. has(value):检查一个对象是否存在于WeakSet中,在里面 true 否则 false

示例代码

// 创建一个WeakSet实例  
const weakSet = new WeakSet();  
  
// 创建一些对象  
const obj1 = {};  
const obj2 = {};  
  
// 向WeakSet中添加对象  
weakSet.add(obj1);  
weakSet.add(obj2);  
  
// 检查对象是否存在于WeakSet中  
console.log(weakSet.has(obj1)); // 输出: true  
console.log(weakSet.has(obj2)); // 输出: true  
  
// 尝试添加重复的对象(不会添加)  
weakSet.add(obj1);  
console.log(weakSet.size); // 注意:WeakSet没有size属性,这里只是为了说明不会添加重复对象  
  
// 从WeakSet中删除对象  
weakSet.delete(obj1);  
console.log(weakSet.has(obj1)); // 输出: false  
  
// 尝试遍历WeakSet(会报错或无效)  
// for (const item of weakSet) {  
//     console.log(item); // 这里无法执行,因为WeakSet不能遍历  
// }

总结

Set

  • 成员唯一、无序且不重复

  • 键值与键名是一致的(或者说只有键值,没有键名)

  • 可以遍历,方法有 add, delete,has

WeakSet

  • 成员都是对象

  • 成员都是弱引用,可以被垃圾回收机制回收,可以用来保存 DOM 节点,不容易造成内存泄漏

  • 不能遍历,方法有 add, delete,has

Map

  • 本质上是健值对的集合,类似集合

  • 可以遍历,方法很多,可以跟各种数据格式转换

WeakMap

  • 只接受对象作为健名(null 除外),不接受其他类型的值作为健名

  • 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾机制回收,此时键名是无效的

  • 不能遍历,方法有 get、set、has、delete  

内存泄漏 

内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

Javascript 是一种高级语言,它不像 C 语言那样要手动申请内存,然后手动释放,Javascript 在声明变量的时候自动会分配内存,普通的类型比如 number,一般放在栈内存里,对象放在堆内存里,声明一个变量,就分配一些内存,然后定时进行垃圾回收。垃圾回收的任务由 JavaScript 引擎中的垃圾回收器来完成,它监视所有对象,并删除那些不可访问的对象。

基本的垃圾回收算法称为“标记-清除”,定期执行以下“垃圾回收”步骤:

  • 垃圾回收器获取根并“标记”(记住)它们。

  • 然后它访问并“标记”所有来自它们的引用。

  • 然后它访问标记的对象并标记它们的引用。所有被访问的对象都被记住,以便以后不再访问同一个对象两次。

  • 以此类推,直到有未访问的引用(可以从根访问)为止。

  • 除标记的对象外,所有对象都被删除。

标签:对象,引用,WeakMap,回收,weakmap,内存,weakset,WeakSet
From: https://blog.csdn.net/m0_66167494/article/details/142854853

相关文章

  • 内存管理-31-系统内存统计-6-dumpsys meminfo
     一、dumpsysmeminfo命令数据格式Exynos:/#dumpsysmeminfoApplicationsMemoryUsage(inKilobytes):Uptime:9463100Realtime:9463100TotalPSSbyprocess:452,701K:com.sumsung.speech(pid2297)266,607K:system(pid936)79,088K:vendor.q......
  • 计算机基础(cpu,内存,硬盘)
    计算机基础(cpu,内存,硬盘)内存:负责硬盘等硬件上的数据与CPU之间数据交换处理;缓存系统中的临时数据。断电后数据丢失。硬盘:​ 存储资料和软件等数据的设备,有容量大,断电数据不丢失的特点。流程​ 简单来说,硬盘用来存储程序和数据,当运行程序时,CPU首先接受到命令,之后CPU是告诉......
  • Linux多进程通信--管道、消息队列、共享内存
    转载至https://www.cnblogs.com/LUO77/p/5816326.html多进程:首先,先来讲一下fork之后,发生了什么事情。由fork创建的新进程被称为子进程(childprocess)。该函数被调用一次,但返回两次。两次返回的区别是子进程的返回值是0,而父进程的返回值则是新进程(子进程)的进程id。将子进程id返......
  • OS-Nachos内存管理
    实验目的在Nachos现有页表的基础上,增加TLB快表机制,使得在做虚拟地址到物理地址的转换时,优先从TLB快表中读取;针对TLB增加NRU置换算法;除实验源码和实验结果截图以外,需提供以下文字解释说明:解释说明nachos-xuserProgName的启动过程及原生Nachos系统中的内存访问过程;解释说明......
  • 在 C 语言中通过指针访问结构体内存
    在C语言中,指针是用于引用内存地址的变量,通过指针可以有效地访问和操作内存。即使未显式创建结构体实例,只要指向的内存区域足够大且对齐方式正确,指针也能够按照特定结构体的布局访问数据。以下是这个机制的详细解读。1.指针与内存布局指针的类型(如Block*)告诉编译器如何解释......
  • C语言中的指针与内存管理:两种情况分析
    在C语言中,指针的使用和内存管理是非常重要的概念。在本文中,我们将分析两种情况:一种是通过指针修改结构体内容,另一种是错误地尝试通过指针分配新的内存。我们将详细探讨这两种情况中的内存管理问题和如何避免常见的错误。第一例:通过指针修改结构体内容以下是第一段代码:#includ......
  • 【C语言】动态内存管理及相关笔试题
    文章目录一、为什么有动态内存分配二、malloc和free1.malloc函数的使用2.free函数的使用三、calloc和realloc1.calloc函数的使用2.realloc函数的使用四、常见动态内存分配的错误五、动态内存经典笔试题题1题2题3六、总结C/C++中程序内存区域划分一、为什么有动态......
  • 曝iPhone 18 Pro Max首发2nm芯片:内存升级12GB
    10月15日消息,业内人士手机晶片达人爆料,2026年的iPhone18系列首发2nm处理器A20,这颗芯片采用全新的WMCM封装,内存同时升级到12GB。结合此前爆料的信息,目前可以确定顶配版iPhone18ProMax能首发A20,并配备12GB内存,至于iPhone18,按照苹果的差异化策略,有可能无缘2nm和12GB内存。作......
  • 【汇编语言】寄存器(内存访问)(二)—— DS和[address]
    前言......
  • JVM调优第五天——堆内存模型【面试问题】
            Java虚拟机(JVM)是Java程序运行的基础,它为Java程序提供了一个与硬件和操作系统无关的运行环境。在JVM中,堆内存是程序运行期间,存储对象实例和数组的主要区域。本文将深入探讨Java堆内存的各个方面,包括对象内存布局、JVM内存溢出、垃圾回收机制,以及堆内存的划分和Y......