JavaScript高级:垃圾回收机制

1 引言

垃圾回收机制(Garbage Collection)简称 GC。js中的内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。

 

 2 内存的生命周期

js环境中分配的内存,一般有如下的生命周期:

1. 内存分配:当我们声明变量、函数、对象的时候,系统会自动为它们分配内存;

2. 内存使用:即读写内存,也就是使用变量、函数等;

3. 内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存;

说明:

1. 全局变量一般不会回收(关闭页面才会被回收);

2. 一般情况下局部变量的值,不被使用了,会自动被回收;

3. 程序中分配的内存 由于某种原因,程序未释放或无法释放叫做内存泄漏;(1.下面会提到两个对象相互引用会造成内存泄漏;2. 闭包的一个缺点就是会造成内存泄漏)

3 垃圾回收机制的算法说明

3.1 堆栈空间分配的区别

1. 栈(操作系统):由于操作系统自动分配释放函数的参数值、局部变量等,基本数据类型放到栈里面;

2. 堆(操作系统):一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收复杂数据类型放到堆里面;

3.2 常见浏览器的垃圾回收算法

3.2.1 引用计数算法

IE 浏览器采用的是引用计数算法,定义 “内存不再使用”, 就是看一个对象是否有指向它的引用,没有被引用了,就回收。

3.2.1.1 算法思路

1. 跟踪记录被引用的次数;

2. 如果被引用了一次,那么记录次数就为1, 多次被引用, 则++;

3. 如果减少一个引用就减一, -- ;

4. 如果引用次数是0, 则释放内存;

3.2.1.2 绘图说明

代码示例1:

const arr = [1, 2, 3]
arr = null

数组是复杂数据类型,所以在栈中存的是地址,arr 通过栈中的地址找到堆中的 [1, 2, 3]

<1>. 当执行第一行代码时:

<2>. 当执行第二行代码时:

此时arr被赋值null, null数简单数据类型, 存在栈中

<3>. 被引用次数为0,就会自动被回收了


代码示例2;

let person = {
      name: '张三',
      age: 18
}
let person2 = person
person = 1
person = null

<1>. 代码从上往下执行,对象是复杂数据类型,栈中存地址,堆中存的是数据:

 

<2>. 当代码执行到 let person2 = person 时

将person赋值给person2, 但是复杂数据类型赋的是地址, 所以此时 perosn2 与 person指向相同的地址, 所以person 和 person2指向堆中相同的数据,引用次数变为了 2

<3>.当执行 person = 1 时

 此时person被1赋值, 1属于简单数据类型,存在栈中, 地址改变了,找不到堆中的数据了,所以引用次数减 1

<4>.当执行person2 = null 时

跟上面一样,person2被赋值了简单的数据类型,不再指向堆中的数据,被引用次数再次减去1, 变为了0 此时堆中的数据没有被引用了, 会被系统自动回收

3.2.1.3 引用计数法存在的问题

嵌套(循环)引用问题

代码示例:

function fn(){
   let obj1 = {}
   let obj2 = {}

   obj1.a = obj2
   obj2.a = obj1

   return '引用次数无法回收!'
}

fn()

<1>.当执行        let obj1 = {}
                          let obj2 = {}     这两行代码时,按道理,函数作用域内属于局部作用域,使用完,会被系统回收,


<2>. 但是出现了这两行代码, 问题就出现了,   obj1.a = obj2
                                                                             obj2.a = obj1

所以,如果两个对象相互引用,尽管它们已不再被使用,垃圾回收器也不会进行回收,就会导致内存泄漏

3.2.2 标记清除法

算法思想:

1. 标记清除法将 “不再引用的对象” 定义为 “无法到达的对象”

2. 就是从根部(在JS中就是从全局对象)出发定时扫描内存中的对象,反是能从根部到达的对象,都是还需要使用的

3. 那些无法从根部出发而触及到的对象被标记为不再使用的,稍后进行回收


所以,标记清除法 解决了引用计数法的嵌套引用的问题

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

浅析HTTP协议

首先&#xff0c;前端请求后端数据&#xff0c;后端响应数据给前端&#xff0c;这是我们大家都知道的&#xff0c;那其中所涉及到的数据传输协议又是什么呢&#xff1f;这个传输规范就是我们大名鼎鼎的HTTP协议&#xff01; 什么是HTTP协议&#xff1f; HTTP&#xff08;超文本…

【医学图像隐私保护】PLAN方法:解决 GAN 生成医学图像 Latent 空间中的隐私保护

PLAN方法&#xff1a;解决 GAN 生成医学图像 Latent 空间中的隐私保护方法 PLAN 原理StyleGAN 生成视网膜图k-SALSA 生成视网膜图PLAN方法 生成视网膜图 总结 PLAN 原理 论文&#xff1a;https://arxiv.org/abs/2307.02984 代码&#xff1a;https://github.com/perceivelab/P…

第二证券:深夜突发,油价大涨!惊魂一夜,5700亿市值蒸发

当地时间1月25日&#xff0c;美股三大股指延续涨势&#xff0c;前一日大涨的抢手中概股走势分解。成绩低于预期的特斯拉单日大跌逾12%&#xff0c;总市值蒸腾超越5700亿元人民币&#xff0c;其后市目标价还遭多家组织下调。 从隔夜发布的重要经济及政策数据看&#xff0c;美国…

【RabbitMQ】死信(延迟队列)的使用

目录 一、介绍 1、什么是死信队列(延迟队列) 2、应用场景 3、死信队列(延迟队列)的使用 4、死信消息来源 二、案例实践 1、案例一 2、案例二&#xff08;消息接收确认 &#xff09; 3、总结 一、介绍 1、什么是死信队列(延迟队列) 死信&#xff0c;在官网中对应的单词…

【c语言】扫雷

前言&#xff1a; 扫雷是一款经典的单人益智游戏&#xff0c;它的目标是在一个方格矩阵中找出所有的地雷&#xff0c;而不触碰到任何一颗地雷。在计算机编程领域&#xff0c;扫雷也是一个非常受欢迎的项目&#xff0c;因为它涉及到许多重要的编程概念&#xff0c;如数组、循环…

基于卡尔曼滤波的平面轨迹优化

文章目录 概要卡尔曼滤波代码主函数代码CMakeLists.txt概要 在进行目标跟踪时,算法实时测量得到的目标平面位置,是具有误差的,连续观测,所形成的轨迹如下图所示,需要对其进行噪声滤除。这篇博客将使用卡尔曼滤波,对轨迹进行优化。 优化的结果为黄色线。 卡尔曼滤波代码…

带【科技感】的Echarts 图表

Echarts脚本在线地址 https://cdn.jsdelivr.net/npm/echarts5.4.3/dist/echarts.min.js 引入Echarts 脚本后粘贴代码 vue2 代码&#xff1a; <template><div><div ref"col-2-row-2" class"col-2-row-2"></div></div> <…

PHP - Yii2 异步队列

1. 前言使用场景 在 PHP Yii2 中&#xff0c;队列是一种特殊的数据结构&#xff0c;用于处理和管理后台任务。队列允许我们将耗时的任务&#xff08;如发送电子邮件、push通知等&#xff09;放入队列中&#xff0c;然后在后台异步执行。这样可以避免在处理大量请求时阻塞主应用…

sklearn 学习-混淆矩阵 Confusion matrix

混淆矩阵Confusion matrix&#xff1a;也称为误差矩阵&#xff0c;通过计算得出矩阵的结果用来表示分类器的精度。其每一列代表预测值&#xff0c;每一行代表的是实际的类别。 from sklearn.metrics import confusion_matrixy_true [2, 0, 2, 2, 0, 1] y_pred [0, 0, 2, 2, 0…

ICMP协议详解

ICMP&#xff08;Internet Control Message Protocol&#xff09;协议是一个网络层协议。 一个新搭建好的网络&#xff0c;往往需要先进行一个简单的测试&#xff0c;来验证网络是否畅通&#xff1b;但是IP协议并不提供可靠传输。如果丢包了&#xff0c;IP协议并不能通知传输层…

【Kafka】开发实战和Springboot集成kafka

目录 消息的发送与接收生产者消费者 SpringBoot 集成kafka服务端参数配置 消息的发送与接收 生产者 生产者主要的对象有&#xff1a; KafkaProducer &#xff0c; ProducerRecord 。 其中 KafkaProducer 是用于发送消息的类&#xff0c; ProducerRecord 类用于封装Kafka的消息…

2023中国高速公路信息化发展盘点

文章目录 前言一、政策规范(一)《加快建设交通强国五年行动计划(2023—2027年)》(二)《关于推进公路数字化转型 加快智慧公路建设发展的意见》(三)《公路工程设施支持自动驾驶技术指南》(四)《贵州省智慧高速公路建设指南(试行)》(五)江苏省《智慧公路车路协同路…

监听元素宽高变化---new ResizeObserver

参考&#xff1a;ResizeObserver API详解-CSDN博客 有的时候需要监听某个元素的宽高变化&#xff0c;这个时候可以使用JS的 resizeObserver 钩子函数。 用于监视元素的大小变化。它可以观察一个或多个 DOM 元素&#xff0c;以便在元素的大小或形状发生变化时触发回调函数。R…

VsCode提高生产力的插件推荐-持续更新中

别名路径跳转 自定义配置// 文件名别名跳转 "alias-skip.mappings": { "~/": "/src", "views": "/src/views", "assets": "/src/assets", "network": "/src/network", "comm…

深圳工业元宇宙赋能新型工业化,推动工业制造业数字化转型发展

在当今数字化时代&#xff0c;工业制造业正面临着巨大的变革。随着技术的不断进步&#xff0c;工业元宇宙的概念逐渐成为推动工业制造业数字化转型的重要力量。深圳作为中国的高科技之都&#xff0c;在这方面走在了前列&#xff0c;积极探索工业元宇宙的应用&#xff0c;赋能新…

引领未来:云原生在产品、架构与商业模式中的创新与应用

文章目录 一、云原生产品创新二、云原生架构设计三、云原生商业模式变革《云原生落地 产品、架构与商业模式》适读人群编辑推荐内容简介目录 随着云计算技术的不断发展&#xff0c;云原生已经成为企业数字化转型的重要方向。接下来将从产品、架构和商业模式三个方面&#xff0c…

【洛谷】P1135奇怪的电梯(DFS)

这题利用 dfs 解决&#xff0c;编程实现比较简单。 具体来说&#xff0c;每层楼有两种可能&#xff0c;上楼或下楼&#xff0c;因此可以形成一个以 a 楼为根的二叉树&#xff0c;因此只需一个 for 循环遍历某个父节点的两个子节点&#xff0c;之后递归就行。 易错点&#xff…

浅出深入-机器学习

文章目录 一、K近邻算法1.1 先画一个散列图1.2 使用K最近算法建模拟合数据1.3 进行预测1.4 K最近邻算法处理多元分类问题1.5 K最近邻算法用于回归分析1.6 K最近邻算法项目实战-酒的分类1.6.1 对数据进行分析1.6.2 生成训练数据集和测试数据集1.6.3 使用K最近邻算法对数据进行建…

手把手教你用plotly绘制excel中常见的8种图表

目录&#xff1a; 0. 准备工作 1. 柱状图 2. 条形图 3. 折线图 4. 面积图 5. 饼图与圆环图 6. 散点图 7. 气泡图 8. 极坐标(雷达图) 0. 准备工作 我这边是在jupyterlab中演示的plotly图表&#xff0c;如果只安装plotly是无法正常显示图表的&#xff08;会显示为空白…

Mac怎么录屏?简单易懂,关键技巧分享!

随着时代的变迁&#xff0c;人们对mac电脑的使用需求也越来越多样化。其中&#xff0c;屏幕录制成为了很多用户的常用需求&#xff0c;比如录制教程、游戏视频、会议记录等。可是很多用户不知道mac怎么录屏。本文将为你详细介绍两种mac录屏的方法&#xff0c;让大家轻松学会如何…