【JavaScript高级】内存管理与闭包:垃圾回收GC、闭包定义、访问和执行过程、内存泄漏

2023-11-02

内存管理

所有编程语言,在代码的执行过程中都需要给它分配内存,不同的是:某些编程语言需要我们自己手动的管理内存,某些编程语言会可以自动帮助我们管理内存。

内存管理的生命周期

  1. 申请:申请你需要的内存
  2. 使用:存放一些东西,比如对象等
  3. 释放

不同的编程语言对于第一步和第三步会有不同的实现:

  • 手动管理内存:如C,C++
  • 自动管理内存:比如Java、JavaScript、Python

JavaScript 的内存管理是自动的、无形的:我们创建的原始值、对象、函数……这一切都会占用内存。但我们不需要手动对它们进行管理,JavaScript引擎会帮我们处理好它。

JavaScript会在定义数据时为我们分配内存:

  • JS对于原始数据类型内存的分配会在执行时,直接在栈空间进行分配
  • JS对于复杂数据类型内存的分配会在堆内存中开辟一块空间,变量引用其内存地址(如对象)

数据类型:

  • 基本数据类型(值类型):string、number、boolean、undefined、null、symbol
  • 复杂数据类型(引用类型):object、function、array

垃圾回收GC

内存大小有限,当内存不再需要时,我们需要对其进行释放,以腾出更多的内存空间。

手动管理内存的语言中,我们需要通过一些方式自己来释放不再需要的内存,比如free函数:

  • 这种方式非常低效,影响我们编写逻辑的代码的效率
  • 对开发者要求很高,一不小心会产生内存泄露

大部分现代编程语言都是有自己的垃圾回收机制

  • Garbage Collection,简称GC;
  • 对于那些不再使用的对象,我们称之为垃圾,需要被回收,以释放更多的内存空间
  • 而我们的语言运行环境,比如Java的JVM,JavaScript的js引擎都有内存垃圾回收器
  • 垃圾回收器我们也会简称为GC,很多地方的GC指的是垃圾回收器

GC怎么知道哪些对象是不再使用的呢?这就引出了GC的实现及对应算法。

引用计数(Reference counting)

  • 当一个对象有一个引用指向它时,那么这个对象的引用就+1
  • 当一个对象的引用为0时,这个对象就可以被销毁掉
  • 弊端:会产生循环引用

在这里插入图片描述

标记清除(mark-Sweep)

  • 核心思路是可达性(Reachability)
  • 算法内容:设置一个根对象(root object),垃圾回收器会定期从这个根开始,找所有从根开始有引用到的对象,对于那些没有引用到的对象,就认为是不可用的对象(也就是垃圾)
  • 可以很好的解决循环引用的问题

在这里插入图片描述

闭包

定义

在计算机科学中对闭包的定义(维基百科):

  • 是在支持 头等函数 的编程语言中,实现词法绑定的一种技术
  • 在实现上是一个结构体,它存储了一个函数和一个关联的环境(相当于一个符号查找表)

举个例子:

var name = "name"
var age = 18
var address = "address"

function foo() {
    var message = "Hello World!"
    console.log(message, name, age, address);
}

这段代码里foo函数是可以访问到name、age、address的,因为它们在一个闭包里。

MDN对JavaScript闭包的解释:

  • 一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)
  • 闭包让你可以在一个内层函数中访问到其外层函数的作用域
  • 在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来

总结:

  • 一个普通的函数function,如果它可以访问外层作用域的自由变量,那么这个函数和周围环境就是一个闭包
  • 从广义的角度来说:JavaScript中的函数都是闭包
  • 从狭义的角度来说:JavaScript中一个函数,如果访问了外层作用域的变量,那么它是一个闭包

闭包的访问和执行过程

看这里:JavaScript闭包的那些事~

内存泄漏

为什么会内存泄漏?

  • 在全局作用域下一些变量对一些的函数对象有引用,而函数对象的作用域中AO有引用,最终会造成这些内存都无法被释放
  • 闭包会造成内存泄露,就是上述的引用链中的所有对象都是无法释放的

如何解决:a原先是对函数对象的引用。这里我们把它赋值为null,这样函数对象就是不可达的,在GC的下一次检测中就会被销毁掉。

var a=null

浏览器的优化

V8会把AO里不用的属性释放掉。

这里只用到了count,没有用到name,所以name就被释放掉了:
在这里插入图片描述

参考

coderwhy的课
js中的内存管理
JavaScript的内存管理
JS内存管理
JavaScript闭包的那些事~

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【JavaScript高级】内存管理与闭包:垃圾回收GC、闭包定义、访问和执行过程、内存泄漏 的相关文章

  • 驱动程序信息:driver.version:未知,使用 ChromeDriver v78.0.3904.70 和 Chrome 浏览器 v78.0.3904.97

    我使用的是java 1 8和chrome浏览器版本78 0 3904 97 我正在尝试使用 chrome 驱动程序版本执行我的 selenium 脚本代码78 0 3904 70 但在执行时我面临以下问题并且 chrome 立即崩溃 Pic
  • 如何在jsp中使用javascript动态创建下拉框?

    我正在尝试动态创建下拉框 就像当我单击添加按钮时它必须创建新的下拉框 下拉列表还包含动态值 例如需要当前年份并且必须显示最多五年 请建议我这样做 谢谢 这是我尝试过的代码 JavaScript 代码 function Add var nam
  • Java 7 中 Object 和 int 的比较

    最近我偶然发现了一个问题 让我停下来思考 对我来说 下面的代码应该总是会触发错误 但是当我的一位同事问我为什么 Eclipse 没有显示错误时 我无法回答任何问题 class A public static void main String
  • 验证动态添加的输入字段

    我用过this http docs jquery com Plugins Validation以下表单的 jquery 验证插件
  • 当用户输入/删除时,使文本字段中的提示消失/重新出现[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 有谁知道我怎样才能在我的搜索栏中做出
  • Angular2 - 防止复选框被选中

    我有一个每行包含一个复选框的表 在表头中 我有一个Check All切换所有表格行框的复选框 我正在尝试实现一些逻辑 如果复选框的数量将超过特定限制 则显示错误并且不切换表行复选框或checkall盒子本身 有一个问题允许checkAll即
  • 特别更改画布上的笔画不透明度,但不更改颜色

    我有一个漂亮整洁的脚本 可以循环显示颜色 并且与 xxxxxx格式 但我想改变透明度 有没有办法做到这一点 我指的是ctx strokeStyle 这是当前的代码 canvas strokeStyle 16777215 s length i
  • 我可以关闭并重新打开套接字吗?

    我学习了一个使用套接字的例子 在此示例中 客户端向服务器发送请求以打开套接字 然后服务器 侦听特定端口 打开套接字 一切都很好 套接字从双方 客户端和服务器 打开 但我仍然不清楚这个东西有多灵活 例如 客户端是否可以关闭一个打开的 从两端
  • Java .split("|") 不工作

    我刚刚遇到了一个问题分割法 http docs oracle com javase 6 docs api java lang String html split 28java lang String 29for 字符串不适用于字符 作为一个
  • 使用链接列表插入优先级队列的方法

    首先 我觉得我应该提到这是一项作业 我并不是在寻找直接的代码答案 只是为了指出正确的方向 我们被要求在链表中实现优先级队列 我正在努力编写 insert 函数的第一部分 在代码中我尝试检查是否head包含任何内容 如果没有则设置为head
  • 计算移动的球与移动的线/多边形碰撞的时间(2D)

    我有一个多边形 里面有一个移动的球 如果球撞到边界 它应该反弹回来 My current solution I split the polygon in lines and calculate when the ball hits the
  • 谷歌绘制具有相同比例的多个系列的图表

    我正在寻找一种在图形上显示多个系列的方法 这些系列具有相同的比例但仅显示一次 正如你在这里看到的 http jsfiddle net Youkoal d3xwnqdu http jsfiddle net Youkoal d3xwnqdu 我
  • Checkstyle - 方法按修饰符排序

    是否可以添加到 checkstyle 规则以按修饰符对类中的方法进行排序 我的意思是开头的公共方法和最后的私有方法 MethodsOrderCheck做这个工作 检查文档 https www qulice com qulice checks
  • 如何优化 Three.js 中多个 sphereGeometry 的渲染?

    我想优化 Three js 中 sphereGeometry 的渲染 因为它成为我的程序的瓶颈 javascript程序如下所示 var sphereThree for var idSphere 0 idSphere lt numSpher
  • 角度距离计算

    我正在使用角度制作距离计算应用程序 Html
  • CSS 或 Javascript - 如果背景图像未加载,则显示后备文本[重复]

    这个问题在这里已经有答案了 如果徽标图形文件未加载或丢失 如何显示文本而不是徽标 我有带有背景 PNG 图像的 div div class iHaveBgImage this text should be displayed if bg i
  • JSP 和 scriptlet

    我知道现在使用 scriptlet 被认为是禁忌 没关系 我会同意Top Star的话 因为我目前只是Java新手 到目前为止我听到的是 它是为了让设计师的生活更轻松 但我想知道 这是否与JSP页面的性能有关 另一方面 如果只是为了 让设计
  • 将带有时区的 Joda-Time `DateTime` 转换为没有时区的 DateTime?

    Given a DateTime http www joda org joda time apidocs org joda time DateTime html例如2015 07 09T05 10 00 02 00 using 乔达时间 h
  • Chrome + 另一个进程:进程间通信比 HTTP/XHR 请求更快?

    我有一个进程 1 对视频流进行实时图像处理 我需要在 Chrome 中的 HTML 页面中渲染该视频 同一台计算机上的进程 2 在canvas or img or videoHTML5 元素 由于我有 1000x1000 像素 x 3 字节
  • Java,如何管理线程读取socket(websocket)?

    我有一个 WebSocket 服务器 我的服务器创建一个新线程来处理新连接 该线程一直处于活动状态 直到 websocket 中断 我的问题 对于 1 000 000 个连接 我需要 1 000 000 个线程 我如何通过一个线程处理多个

随机推荐

  • 模型保存的两种类型torch.save

    torch save model model face pt 一个常见的PyTorch函数是使用 pt文件扩展名来保存张量 model是我训练后的模型 后面的参数 model face pt 就是我模型保存的类名 存放同一文件夹下 当然可以
  • 数据库系统教程(第二版何玉洁)课后数据库上机实验答案

    附录C 上机实验 C 1 第4章上机实验 陈宇超 仅供参考 下列实验均使用SQL Server 的SSMS工具实现 1 用图形化方法创建符合如下条件的数据库 创建数据库的方法可参见本书附录A l 数据库名为 学生数据库 l 主要数据文件的逻
  • 常用的java虚拟机参数_Java虚拟机参数分析 - PerfMa

    参数查询 支持查询一到多个 JVM 参数 向用户展示每个 JVM 参数的详细信息 包括含义 用法等 并可查看社区对此参数的相关讨论 支持两种输入格式 直接输入一个或多个参数名 示例 Xms Xmx Xmn Xss MaxPermSize M
  • 超详细的OpenCV入门教程,12小时带你吃透OpenCV。

    OpenCV简介 OpenCV是一个基于Apache2 0许可 开源 发行的跨平台计算机视觉和机器学习软件库 可以运行在linux Windows Android和MAC OS操作系统上 1 它轻量级而且高效 由一系列 C 函数和少量 C
  • vue中scoped与/deep/深度选择器原理总结

    最近在写一个vue element ui项目 使用element ui某些组件修改样式时 老是需要加上 deep 深度选择器 以前只是知道这样用 但是还不清楚他的原理 这次就来好好的梳理一下 1 首先我们需要知道css中的属性选择器 w3c
  • Introduction to Causal Inference:Chapter 1因果推断概论

    本文是学习brady neal于2020年开设的因果推断课程Introduction to Causal Inference的记录 概述 本chapter主要分四个部分 辛普森悖论 为什么相关性不是因果关系 什么展示了因果关系 在观测性研究
  • 七、PyQt5实现Python界面设计_滑块控件(QSlider)与计数器控件(QSpinBox)

    目录 一 QSlider滑块控件 1 简介 2 常用函数 3 代码演示 二 QSpinBox计数器控件 1 简介 2 常用函数 3 代码演示 一 QSlider滑块控件 1 简介 1 水平或者垂直的滑动控件 一般用来设置数字 快速滑动来调整
  • 「第二篇」全国一等奖,经验帖。

    点击上方 大鱼机器人 选择 置顶 星标公众号 福利干货 第一时间送达 阅读文本大概需要 6 分钟 0 前言 本文作者 谢斌 曾经获得2017年控制题 板球控制系统 全国一等奖 他之前有写过几篇关于比赛的文章 大家可以点击阅读 全国一等奖 他
  • 如何使用html制作网页

    如何使用html制作网页 一 html简介 1 1概念 HTML即HyperText Mark up Language 意思是超文本标记语言 HTML不是一种编程语言 而是一种标记语言 超文本指的是超链接 标记指的是标签 是一种用来制作网页
  • 如何保护单例不被反射修改?

    public class Safety private static Safety instance new Safety private Safety if instance null throw new RuntimeException
  • hadoop生态系统的详细介绍-详细一点

    前提 日常喜欢看一些微信分享的好文 总结下来 可以作为过滤器吧 节约更多人的时间 在这里引用的是别人的文章 对原文的作者表示感谢 确实写的很好 hadoop生态系统的详细介绍 简介 Hadoop是一个开发和运行处理大规模数据的软件平台 是A
  • Kafka By the sea——kafka的使用场景

    文章目录 消息队列概述 消息队列应用场景 异步处理 应用解耦 流量削锋 日志处理 消息通讯 消息中间件示例 电商系统 日志收集系统 常用消息队列 ActiveMQ Kafka 消息队列概述 消息队列中间件是分布式系统中重要的组件 主要解决应
  • js怎么做延迟函数delay

    const delay ms gt new Promise resolve reject gt setTimeout resolve ms const getData status gt new Promise resolve reject
  • 评分算法_协同过滤推荐算法:评分预测准确性评估

    纸上得来终觉浅 绝知此事要躬行 宋 陆游 冬夜读书示子聿 对于评分预测常用的准确性评测指标是均方根误差RMSE和平均绝对误差MAE RMSE 均方根误差 对大的偏差更敏感 MAE 平均绝对值误差 注意 R 表示数据集合的长度 准确性指标计算
  • PADS Router VX2.7 操作界面以及常用设置

    打开方式 直接双击Router或者从layout中打开 打开Router 右击工具栏 选择自己想要使用的工具 项目浏览器 输出窗口 电子表格 导航窗口 都在右上角 标志工具栏中 如果不小心关掉 点击即可恢复 坐标以及单位 设置在 工具栏中的
  • 聊聊软件测试的那些事

    笔者入行软件测试行业也有两年左右的时间了 这两年中 在工作中也学习 积累了一些知识 但是每每谈及理论 又好像怎么也说不清一些东西的定义 其实很多人认为 知识学习了会用就可以 但软件测试的道路上 打好基础是很重要的 有些东西你知道但无法清晰表
  • 【leetcode每日刷题】214. 最短回文串

    给定一个字符串 s 你可以通过在字符串前面添加字符将其转换为回文串 找到并返回可以用这种方式转换的最短回文串 示例 1 输入 aacecaaa 输出 aaacecaaa 示例 2 输入 abcd 输出 dcbabcd 解法 KMP算法 假设
  • BUCK电路输入电容计算

    输入电容决定了输入电压的纹波 对于Buck变换器的输入端来说 输入电流是不连续的 在开关管导通的时候会有极大的阶跃电流 芯 片 BUCK控制器 时 间 2021 04 27 说 明 适用于稳态和动态负载 在Buck变换器的输入电压最小时 满
  • Qt中自定义结构体的使用

    Qt的自定义结构体Qt是不认识的 下面就直接列出使用方法 第一步 建议把所需的结构体放在一个单独头文件中 防止头文件相互包含 gg 而且还有条件编译的头自动生成 直接向工作添加C 头文件 自己把名字取好就行了 注意 这样会在 pro中 HE
  • 【JavaScript高级】内存管理与闭包:垃圾回收GC、闭包定义、访问和执行过程、内存泄漏

    文章目录 内存管理 垃圾回收GC 引用计数 Reference counting 标记清除 mark Sweep 闭包 定义 闭包的访问和执行过程 内存泄漏 浏览器的优化 参考 内存管理 所有编程语言 在代码的执行过程中都需要给它分配内存