【JS】—垃圾回收机制

一、指令材料

1.定义

JavaScript(JS)的垃圾回收机制是一种自动管理内存的过程,它有助于释放不再使用的内存,以避免内存泄漏和提高程序的性能。
JavaScript的垃圾回收机制是一种自动管理内存的方式,以确保不再被引用的对象可以被垃圾回收,释放内存。

2.分类

2-1. 引用计数算法

引用计数算法通过跟踪每个对象被引用的次数来决定何时回收内存。当一个对象的引用计数为零时,它就会被垃圾回收.

2-2. 循环引用

循环引用是一种特殊情况,其中两个或多个对象互相引用,导致它们的引用计数不会降为零。这时,垃圾回收需要使用更复杂的算法来检测并处理循环引用。

2-3. 标记清除算法

标记清除算法通过标记所有从根对象(通常是全局对象)可达的对象,然后清除未标记的对象来回收内存。

二、 限定条件

JavaScript的垃圾回收机制主要涉及对象的管理,而基本数据类型通常不涉及垃圾回收,因为它们是简单的值,而不是对象。JavaScript的垃圾回收机制更关注于复杂数据类型,如对象和数组。

  1. 数字(Number): 基本数据类型的数字是不需要垃圾回收的,因为它们只是简单的数值,没有引用其他对象或数据。
let x = 42; // 基本数据类型的数字
  1. 字符串(String): 基本数据类型的字符串也不需要垃圾回收,因为它们是不可变的,没有内部引用需要跟踪。
 let name = "John"; // 基本数据类型的字符串
  1. 布尔值(Boolean): 基本数据类型的布尔值也不需要垃圾回收,因为它们只表示真或假。
let isLogged = true; // 基本数据类型的布尔值
  1. 空值(null)和未定义(undefined): 这些特殊的基本数据类型表示缺少值或未定义的值。它们也不需要垃圾回收。
let emptyValue = null; // 空值
let undefinedValue; // 未定义

三、做练习题

1. 引用计数算法

// 把 {name: ‘John’} 代指A
//  A 对象被obj1 引用1次,A 引用计数=1次
let obj1 = { name: 'John' };
//  A 对象被obj2 引用1次,A 引用计数=2次
let obj2 = obj1; // 解除obj1 的引用对象A, A 引用计数 = 1 次
obj1 = null;
// 解除obj2 的引用对象A, A 引用计数 = 0 次
obj2 = null; // 对象A 没有被任何变量引用,将被垃圾回收机制回收

总结归纳:

  1. 引用计数是指一个对象的堆内存空间被引用了几次
  2. 通过=号,给变量赋值对象,引用增加
  3. 通过=号,给变量赋值为null, 解除对象的引用

2-1. 循环引用

function createCircularReference() {// 把 {} 代指 A, A 被obj1 引用1次, A的引用计数 = 1次let obj1 = {}; // // 把 {} 代指 B, B 被obj1 引用1次, B的引用计数 = 1次let obj2 = {}; // // B 被 obj1.circularRef 引用1次, B的引用计数 = 2次obj1.circularRef = obj2; // A 被 obj2.circularRef 引用1次, A的引用计数 = 2次obj2.circularRef = obj1; // 这里有一个循环引用,即obj1和obj2互相引用
}// 当函数执行完毕后,obj1和obj2都会离开作用域,
// 但由于它们互相引用,它们的引用计数不会降为零,
// 垃圾回收需要检测和处理这种循环引用```

总结归纳:

  1. 循环引用,引用计数不会降为零
  2. 循环引用是通过两个对象的属性,相互赋值另外一个对象,实现相互引用

1和2-1对比归纳:

  1. 大括号中无论是否有值,都会开辟新的内存空间
  2. 绑定引用和解除引用都使用=号,

2-2. 手动解除引用

你可以通过将循环引用的其中一个对象设置为null来手动解除引用。这将打破循环引用,允许垃圾回收器正确地识别这些对象并释放它们。

// 循环引用
const obj1 = {};
const obj2 = {};
obj1.ref = obj2;
obj2.ref = obj1;// 手动解除引用obj1.ref = null;
obj2.ref = null;

总结归纳:

  1. 绑定引用和解除引用的属性或对象,要保持一致性

2-3. WeakMap和WeakSet 解除引用

JavaScript提供了WeakMap和WeakSet数据结构,它们允许你存储弱引用(不会阻止垃圾回收的引用)。这些数据结构不会阻止对象被回收,因此可以用于解决循环引用问题。当你不再需要这些引用时,它们会自动被垃圾回收

const obj1 = {};
const obj2 = {};const weakMap = new WeakMap();
weakMap.set(obj1, obj2);
weakMap.set(obj2, obj1);// 当不再需要循环引用时,它们会被自动释放

总结归纳:

  1. 使用 weakMap方法,内存变成弱引用,不受引用计数的影响,自动被回收站回收。

3. 标记清除算法

标记清除算法通过标记所有从根对象(通常是全局对象)可达的对象,然后清除未标记的对象来回收内存。

// 标记所有能够从根对象访问到的对象,通常包括全局变量、当前调用栈中的变量等。标记的对象会被标记为“活动”
function createUser() {let user = {name: 'Alice',age: 30  };return user;
}
// 遍历:垃圾回收器遍历整个对象图,标记所有与活动对象相互引用的对象,以确保不会因为被引用而被清除。
let userData = createUser(); 
// 现在userData不再引用对象
userData = null; // 当userData变为null后,活动对象被解除引用
// 垃圾回收会将这个对象createUser()清除

总结归纳:

  1. 标记全局变量下对象,为活动对象
  2. 遍历查询出,哪些活动对象被引用,防止被垃圾回收

总结规律:

  1. 引用计数是指一个对象的堆内存空间被引用了几次
  2. 通过=号,给变量赋值对象,引用增加
  3. 通过=号,给变量赋值为null, 解除对象的引用
  4. 循环引用是通过两个对象的属性,相互赋值另外一个对象,实现相互引用
  5. 循环引用,引用计数不会降为零
  6. 手动解除引用,通过把基本数据类型赋值给变量,解除变量和对象的引用关系
  7. 对象弱引用,使用weakMap和WeakSet方法实现两个对象的弱引用,使用完成后允许垃圾回收
  8. 标记全局变量下对象,为活动对象
  9. 遍历查询出,哪些活动对象被引用,防止被垃圾回收

四、建立新学的知识与旧知识之间的关联

1. js的垃圾回收机制和 delete 删除对象的属性

  1. js的垃圾回收机制,把代码中没有被引用的对象,自动清除该对象所占用的内存空间;delete 删除对象的属性
  2. 两者之间的区别
  • 一个清除未被引用对象的内存空间;一个是删除对象的属性
  • 一个自动清除;一个是手动删除
  • 两者的本质:都是清除掉不需要的东西,达成某个功能
// {name:'xiao'} 被obj1 引用1次,{name:'xiao'} 的引用计数 = 1
let obj1 = {name:'xiao'} 
// 解除 ob1 和 {name:'xiao'} 引用关系, {name:'xiao'}的引用计数 = 0, {name:'xiao'} 将被垃圾回收
obj1 = null
let params = {id: 123,name: 'xiao'phone: '123456789'
}
// 业务需求是,新增时,删除id
if (state === 'add'){delete params.id
}

2. 引用计数算法(暂时想不到与那个旧知识关联,日后补充)

3. 标记清除算法(暂时想不到与那个旧知识关联,日后补充)

五、 转换表述

1. js的垃圾回收机制

垃圾回收机制,就是我们平时去吃火锅时,每一盘菜就是就是一个正在被使用的内存,当菜被吃完后,服务员会把空盘子自动拿走,以保证桌面整洁和提高用户体验。
在这里插入图片描述

2. 引用计数算法

引用计数算法就像我们吃完火锅,一包卫生纸盒,给每个人都发一张,直到卫生纸都发完了,只剩下空纸盒,它就会被垃圾回收。引用计数的本质是,该物品(或对象)对某人或事物,还有没有它的价值。
在这里插入图片描述

3. 循环引用

循环引用就是两个正在热恋的年轻人,两个人相互吸引,都离不开对方,脑海中无时无刻在想着对方,所以引用计数永远不会为零,直到他们分手时,他们之间的引用计数才会变成0
在这里插入图片描述

4. 标记清除算法

标记清除算法就是书桌上有很多东西,比如零食、玩具、书本、笔,然后现在妈妈让你写作业,把无关的东西收拾起来,零食、玩具就会被收拾起来(垃圾回收)。
标记清除算法的本质,把没有使用的东西清除掉。

在这里插入图片描述

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

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

相关文章

Linux Shell 实现一键部署podman

podman 介绍 使用 Podman 管理容器、Pod 和映像。从本地环境中无缝使用容器和 Kubernetes,Podman 提供与 Docker 非常相似的功能,它不需要在你的系统上运行任何守护进程,并且它也可以在没有 root 权限的情况下运行。 Podman 可以管理和运行…

Hive 的函数介绍

目录 ​编辑 一、内置运算符 1.1 关系运算符 1.2算术运算符 1.3逻辑运算符 1.4复杂类型函数 1.5对复杂类型函数操作 二、内置函数 2.1数学函数 2.2收集函数 2.3类型转换函数 2.4日期函数 2.5条件函数 2.6字符函数 三、内置的聚合函数 四、内置表生成函数 五、…

Android Jetpack组件架构:Lifecycle的使用 和 原理

Android Jetpack组件架构:Lifecycle的使用和原理 导言 作为Jetpack中关于生命周期管理的核心组件,Lifecycle组件是其他比如LiveDate和ViewModel等组件的基础,本篇文章主要就将介绍关于Lifecycle的使用和它的运作原理。 Lifecycle的使用 我…

MyBatis 中的插件可以拦截哪些操作

MyBatis 中的插件可以拦截哪些操作 MyBatis 是一个优秀的持久化框架,在实际项目开发中广泛应用。MyBatis 的插件机制可以方便地对 MyBatis 的各个环节进行扩展和定制。在本文中,我们将详细介绍 MyBatis 中的插件机制,并探讨插件可以拦截哪些…

C语言大佬的必杀技---宏的高级用法

C语言大佬的必杀技—宏的高级用法 目录: 字符串化标记的拼接宏的嵌套替换多条语句防止一个文件被重复包含宏和函数的区别 可能大家在学习的时候用得比较少,但是在一些代码量比较大的时候,这样使用,可以大大的提高代码的可读性,…

Dependency ‘org.redisson:redisson:‘ not found解决方法 三种刷新Maven项目的方法

报错情况 在pom中导入redisson包 <dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId> </dependency> 爆红&#xff0c;还显示Dependency org.redisson:redisson: not found。 由于报错已经解决&#xff0c;…

002-第一代硬件系统架构确立及产品选型

第一代硬件系统架构确立及产品选型 文章目录 第一代硬件系统架构确立及产品选型项目介绍摘要硬件架构硬件结构选型及设计单片机选型上位机选型扯点别的 关键字&#xff1a; Qt、 Qml、 信号采集机、 数据处理、 上位机 项目介绍 欢迎来到我们的 QML & C 项目&#xff…

【视觉SLAM入门】8. 回环检测,词袋模型,字典,感知,召回,机器学习

"见人细过 掩匿盖覆” 1. 意义2. 做法2.1 词袋模型和字典2.1.2 感知偏差和感知变异2.1.2 词袋2.1.3 字典 2.2 匹配(相似度)计算 3. 提升 前言&#xff1a; 前端提取数据&#xff0c;后端优化数据&#xff0c;但误差会累计&#xff0c;需要回环检测构建全局一致的地图&…

【AI视野·今日Sound 声学论文速览 第十期】Fri, 22 Sep 2023

AI视野今日CS.Sound 声学论文速览 Fri, 22 Sep 2023 Totally 1 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Sound Papers Performance Conditioning for Diffusion-Based Multi-Instrument Music Synthesis Authors Ben Maman, Johannes Zeitler, Meinard M lle…

【新版】系统架构设计师 - 案例分析 - 架构设计<架构风格和质量属性>

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 案例分析 - 架构设计&#xff1c;架构风格和质量属性&#xff1e;例题1例题2例题3例题4例题5例题6 架构 - 案例分析 - 架构设计&#xff1c;架构风格和质量属性&#xff1e; 例题1 某软件公司为…

Python —— pytest框架

1、认识pytest框架 1、搭建自动化框架的思路与流程 1、搭建自动化测试框架的思路和流程&#xff0c;任意测试手段流程都是一致的&#xff1a;手工测试、自动化测试、工具测试 手工测试&#xff1a;熟悉业务 —— 写用例 —— 执行用例并记录结果 —— 生成测试报告自动化测试…

Spring循环依赖大全

本博客挑出出现大部分情况的循环依赖场景进行分析&#xff0c;分析启动会不会报循环依赖的错误&#xff01; 一、常规的A依赖B&#xff0c;B依赖A&#xff0c;代码如下&#xff1a; Component public class A {Resourceprivate B b; } Component public class B {Resourcepri…

【Java 基础篇】Java函数式接口详解

Java是一门强类型、面向对象的编程语言&#xff0c;但在Java 8引入了函数式编程的概念&#xff0c;这为我们提供了更多灵活的编程方式。函数式接口是函数式编程的核心概念之一&#xff0c;本文将详细介绍Java函数式接口的概念、用法以及一些实际应用。 什么是函数式接口&#…

mall电商项目(学习记录1)

1.简介 mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现,采用Docker容器化部署。前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。后台管理系统包含商品管理、订单管…

一、 计算机网络概论

一、计算机网络概论 1、计算机网络概述 1.1、概念 计算机网络是一个将分散的、具有独立功能的计算机系统&#xff0c;通过通信设备与线路连接起来&#xff0c;由功能完善的软件实现资源共享和信息传递的系统 是一些互连的、自治的计算机系统的集合 以能够相互共享资源的方…

Python函数绘图与高等代数互融实例(八):箱线图|误差棒图|堆积图

Python函数绘图与高等代数互融实例(一):正弦函数与余弦函数 Python函数绘图与高等代数互融实例(二):闪点函数 Python函数绘图与高等代数互融实例(三):设置X|Y轴|网格线 Python函数绘图与高等代数互融实例(四):设置X|Y轴参考线|参考区域 Python函数绘图与高等代数互融实例(五…

蓝桥杯 题库 简单 每日十题 day7

01 啤酒和饮料 题目描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。啤酒每罐2.3元&#xff0c;饮料每罐1.9元。小明买了若干啤酒和饮料&#xff0c;一共花了82.3元。我们还知道他买的啤酒比饮料的数量少&#xff0c;请你…

C/C++运算符超详细讲解(系统性学习day5)

目录 前言 一、运算符的概念与分类 二、算术运算符 三、关系运算符 四、逻辑运算符 五、赋值运算符 六、运算符的优先级 总结 前言 本篇文章是对运算符的具体讲解。 一、运算符的概念与分类 概念&#xff1a; 运算符就是一种告诉编译器执行特定的数学或逻辑操作的符…

红黑树Java实现

文章目录 红黑树1. 概念性质2. 红黑树节点定义3. 红黑树的插入情况1情况2情况3其它细节问题插入代码实现 4. 红黑树的验证5.性能分析 红黑树 1. 概念性质 红黑树也是一种二插搜索树&#xff0c;每一个节点上比普通二插搜索树都增加了一个存储位置表示节点的颜色&#xff0c;可…

【已解决】ubuntu 16.04安装最新版本google chrome出错, 旧版本chrome浏览器安装流程

ubuntu 16.04 按照常规的Chrome 安装流程总是出错如下&#xff1a; Selecting previously unselected package google-chrome-stable. (Reading database ... 231747 files and directories currently installed.) Preparing to unpack google-chrome-stable_current_amd64.de…