当前位置: 首页 > news >正文

浅谈垃圾回收、内存泄漏与闭包

什么是垃圾?

在js中,垃圾通常指的是不再被程序使用的内存或对象。也就是说,垃圾是指程序中分配的内存空间或对象,但不再被程序使用或无法被访问到的内容

function createIncrease() {const doms = new Array(100000).fill(0).map((item, i) => {const dom = document.createElement("div");dom.innerHTML = i;return dom;});function _increase() {doms.forEach((dom) => {dom.innerHTML = Number(dom.innerHTML + 1);});}return _increase;
}
const increase = createIncrease();
const btn = document.querySelector("#btn")
btn.addEventListener("click",increase)

上面的代码当执行createIncrease方法时,会创建一个increase方法,同时也会创建一个拥有100000个元素的doms数组,当btn点击时执行increase方法。此时的doms肯定不能称之为垃圾,因为当btn点击时需要使用doms,这种判断相对来说比较简单

const nums = [1, 2, 3, 4, 5];
const sum = nums.reduce((total, num) => total + num, 0);

上面的代码sum是由nums的每一项相加得出的结果,至于nums还会不会再次被使用,根本没法判断
因此,从上面对垃圾的阐述以及例子可以看出,是否为垃圾是由开发者自己决定的。通俗点说,当一段代码执行完成后不会再被使用,那么可以称之为垃圾

垃圾回收

垃圾回收是JavaScript中一种自动内存管理机制,用于检测和释放不再使用的对象,以便回收内存。垃圾回收器会定期扫描内存中的对象,并标记那些仍然被引用的对象,然后清除未被引用的对象垃圾回收器。换句话说,垃圾回收只回收那些开发者自己都访问不了无法触达的内存空间

垃圾回收算法:JavaScript 垃圾回收器使用不同的算法来确定内存中的对象是否可以被回收。常见的算法包括标记-清除引用计数增量标记等。标记-清除是最常用的算法,它通过标记不再需要的对象,然后清除它们来回收内存

function createIncrease() {const doms = new Array(100000).fill(0).map((item, i) => {const dom = document.createElement("div");dom.innerHTML = i;return dom;});function _increase() {doms.forEach((dom) => {dom.innerHTML = Number(dom.innerHTML + 1);});}return _increase;
}
const increase = createIncrease();
const btn = document.querySelector("#btn");
const flag = true;
function handleClick() {flag = false;if (flag) {increase();btn.removeEventListener("click", handleClick);increase = null;}
}
btn.addEventListener("click", handleClick);
const nums = [1, 2, 3, 4, 5];
const sum = nums.reduce((total, num) => total + num, 0);
nums = null

比如上面的代码:

  • btn被点击时执行increase方法,当点击完成后,移除btn点击事件以及将increase设置为null,此时就会被垃圾回收器回收
  • nums重新赋值为null时,那么之前声明的nums的内容我们就无法再访问,因此就会被回收

内存泄漏

内存泄漏是指当程序中的对象不再被使用,但由于某些原因仍然被保留在内存中,导致内存占用不断增加,最终耗尽可用内存的现象。

const timer = setTimeout(() => {// todo
}, 100);
const nums = [1, 2, 3, 4, 5];
const sum = nums.reduce((total, num) => total + num, 0);

在这里插入图片描述
上面的代码我们声明了一个timer的定时器和一个nums的数组,timer没有清理,nums我们明确以后不会再使用,但是timernums会一直存在内存中,这样就容易引起内存泄漏

常见的内存泄漏情况包括:

  • 未及时清除的计时器如果你创建了一个计时器,但忘记在不再需要时清除它,它将一直存在并持有对相关对象的引用,导致内存泄漏
  • 未解绑的事件监听器如果你绑定了一个事件监听器,但在元素被销毁之前忘记解绑它,这个监听器将一直存在,并可能持有对相关对象的引用,导致内存泄漏
  • 循环引用如果对象之间存在循环引用(例如,对象 A 持有对象 B 的引用,同时对象 B 也持有对象 A 的引用),即使它们不再被使用,垃圾回收器也无法释放它们的内存,导致内存泄漏

当内存泄漏过大时会严重影响我们的代码,因为在开发时为避免内存泄漏,可以采取以下措施:

  • 尽量避免创建不必要的闭包,当不再需要时,显式地解除对闭包的引用
  • 将不再使用的变量设置为 null,以协助垃圾回收
  • 尽量避免循环引用,特别是在闭包中
  • 仔细管理计时器、事件监听器和其他可能持有对对象的引用的机制
  • 使用优化的数据结构和算法,避免不必要的内存占用

闭包

闭包是指一个函数能够访问和操作在其词法作用域以外定义的变量。闭包在JavaScript 中被广泛应用,它可以用于创建私有变量、实现模块化等。由于闭包会使函数引用外部变量,当闭包存在时,垃圾回收器可能无法释放被闭包引用的对象,导致内存泄漏

function createIncrease() {const doms = new Array(100000).fill(0).map((item, i) => {const dom = document.createElement("div");dom.innerHTML = i;return dom;});function _temp() {return doms;}function _increase() {}return _increase;}let increase;btn.addEventListener("click", () => {increase = createIncrease();});

上面的代码当点击事件被执行时对increase重新赋值,而createIncrease方法返回_increase方法,因此,此时doms是一块无法触达的内存空间,那么此时的这块无法触达的内存空间会被回收吗?
未点击之前
在这里插入图片描述
点击后
在这里插入图片描述
从上面的图片可以看出,doms并不会被回收,这是因为_temp_increase方法的闭包环境是一样的,它们共用一个词法环境,因此doms不会被回收


从上面的例子可以看出,闭包导致内存泄漏的原因有:

  • 持有了不再需要的函数引用,会导致函数关联的词法环境无法销毁,导致内存泄漏
  • 当多个函数共享词法环境时,会导致词法膨胀,从而使一些无法触达的内存空间无法回收,导致内存泄漏

相关文章:

浅谈垃圾回收、内存泄漏与闭包

什么是垃圾? 在js中,垃圾通常指的是不再被程序使用的内存或对象。也就是说,垃圾是指程序中分配的内存空间或对象,但不再被程序使用或无法被访问到的内容 function createIncrease() {const doms new Array(100000).fill(0).map((…...

2 月 7 日算法练习- 数据结构-树状数组

树状数组 lowbit 在学习树状数组之前,我们需要了解lowbit操作,这是一种位运算操作,用于计算出数字的二进制表达中的最低位的1以及后面所有的0。 写法很简单: int lowbit(int x){return x &am…...

[AIGC] 开源流程引擎哪个好,如何选型?

开源流程引擎是指一种自动化的工作流解决方案,它可以帮助你管理和协调你的业务流程和决策。但是,在开源世界里,有许多不同的流程引擎可以选择。因此,如何选择适合你的开源流程引擎,是一个具有挑战性和价值的话题。 文章…...

服务器使用过程中遇到常见故障及解决方案(包括蓝屏死机、无法删除的文件如何清理、网络卡、服务器连接不上等)

互联网时代,服务器的安全性和稳定性尤为重要,支撑着整个互联网行业的信息和数据安全。最近经常有客户咨询服务器的日常故障排除方法。由于服务器复杂的硬件结构和繁琐的运行原理,经常会出现这样那样的问题,有时即使是最小的问题也…...

【推荐算法】userid是否需要建模

看到一个din的源码,将userid也构建了emb table。 于是调研了一下。即推荐算法需要建模userid吗? 深度学习推荐算法中user-id和item-id是否需要放入模型中作为特征进行训练呢? 深度学习推荐算法中user-id和item-id是否需要放入模型中作为特…...

图解支付-金融级密钥管理系统:构建支付系统的安全基石

经常在网上看到某某公司几千万的个人敏感信息被泄露,这要是放在持牌的支付公司,可能就是一个非常大的麻烦,不但会失去用户的信任,而且可能会被吊销牌照。而现实情况是很多公司的技术研发人员并没有足够深的安全架构经验来设计一套…...

新概念英语第二册(58)

【New words and expressions】生词和短语(16) blessing n. 福分,福气 disguise n. 伪装 tiny adj. 极小的 possess v. 拥有 cursed …...

java和javascript的区别和联系

Java和JavaScript是两种非常流行的编程语言,尽管它们的名称相似,但实际上它们在设计、用途和运行环境等方面有很大的不同。以下是Java和JavaScript之间的主要区别和联系: 区别 设计目的和用途: Java 是一种通用的、面向对象的编程…...

uniapp中配置开发环境和生产环境

uniapp在开发的时候,可以配置多种环境,用于自动切换IP地址,用HBuilder X直接运行的就是开发环境,用HBuilder X发布出来的,就是生产环境。 1.使用HBuilder X创建原生的uniapp程序 选择vue3 2.什么都不改,就…...

prometheus之mysqld_exporter部署

mysql_exporter部署 下载解压压缩包 mkdir /opt/mysqld_exporter/ cd /opt/mysqld_exporter/ # 修改为自己的软件下载地址 wget http://soft.download/soft/linux/prometheus/mysqld_exporter/mysqld_exporter-0.14.0.linux-amd64.tar.gz tar -zxvf mysqld_exporter-0.14.0.…...

<网络安全>《19 安全态势感知与管理平台》

1 概念 安全态势感知与管理平台融合大数据和机器学习技术,提供可落地的安全保障能力,集安全可视化、监测、预警和响应处置于一体。它集中收集并存储客户I环境的资产、运行状态、漏洞、安全配置、日志、流量等安全相关数据,内置大数据存储和多…...

sqli靶场完结篇!!!!

靶场,靶场,一个靶场打一天,又是和waf斗智斗勇的一天,waf我和你拼啦!! 31.多个)号 先是一套基本的判断 ,发现是字符型,然后发现好像他什么都不过滤?于是开始poc 3213131…...

堆结构的解读

对于数据结构堆来说,堆事一种特定的数据结构,其与二叉树非常类似,但是又与二叉树有所不同,其不同点在于堆不需要左右指针指向孩子节点,而给定一个数组,将数组中的元素进行特定排序之后,就可以得…...

7、Qt5开发及实列(笔记)

文章目录 第二章 Qt5模板库、工具类及控件2.2 容器类2.2.1 QList类 # 2.3 QVariant类 #2.4 算法及正则表达式2.5控件 第二章 Qt5模板库、工具类及控件 2.2 容器类 2.2.1 QList类 //2.2容器类 - QList类QList<QString> list;//声明了一个QList<QString>栈对象{QSt…...

FPGA_ip_Rom

一 理论 Rom存储类ip核&#xff0c;Rom是只读存储器的简称&#xff0c;是一种只能读出事先存储数据的固态半导体存储器。 特性&#xff1a; 一旦储存资料&#xff0c;就无法再将之改变或者删除&#xff0c;且资料不会因为电源关闭而消失。 单端口Rom: 双端口rom: 二 Rom ip核…...

5-3、S曲线生成器【51单片机+L298N步进电机系列教程】

↑↑↑点击上方【目录】&#xff0c;查看本系列全部文章 摘要&#xff1a;本节介绍步进电机S曲线生成器的计算以及使用 一.计算原理 根据上一节内容&#xff0c;已经计算了一条任意S曲线的函数。在步进电机S曲线加减速的控制中&#xff0c;需要的S曲线如图1所示&#xff0c;横…...

Google开源项目风格指南——Java

Google Java Style Guide 谷歌 Java 风格指南 谷歌 Java 风格指南1 简介1.1 术语说明1.2 指导说明 2 源文件基础知识2.1 文件名2.2 文件编码&#xff1a;UTF-82.3 特殊字符2.3.1 空白字符2.3.2 特殊转义序列2.3.3 非ASCII字符 3 源文件结构3.1 许可或版权信息&#xff08;如果存…...

数字图像处理与Python语言实现-常见图像特效(二)

文章目录 9、Splash滤镜10、双色调(Duo-Tone)滤镜11、日光(Daylight)滤镜12、60sTVs效果13、高对比度14、棕褐色/复古滤镜15、晕影效果16、模糊滤镜17、浮雕边缘9、Splash滤镜 在Splash滤镜中,仅某些颜色保持原样,其余颜色转换为灰度。 为了执行此操作,我们将在 HSV 颜…...

学习方法分享

工作上的代码实现&#xff0c;不要过度设计&#xff0c;不要想着炫技&#xff0c;要简单务实&#xff0c;“大道至简”。 学习一个方向&#xff08;模块化&#xff09;的知识&#xff0c;不经意间就会涉及到另一个领域&#xff0c;比如从消息队列存储的顺序读/写&#xff0c;延…...

Python学习路线 - Python高阶技巧 - 拓展

Python学习路线 - Python高阶技巧 - 拓展 闭包闭包注意事项 装饰器装饰器的一般写法(闭包写法)装饰器的语法糖写法 设计模式单例模式工厂模式 多线程进程、线程并行执行多线程编程threading模块 网络编程Socket客户端和服务端Socket服务端编程实现服务端并结合客户端进行测试 S…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

Day131 | 灵神 | 回溯算法 | 子集型 子集

Day131 | 灵神 | 回溯算法 | 子集型 子集 78.子集 78. 子集 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 笔者写过很多次这道题了&#xff0c;不想写题解了&#xff0c;大家看灵神讲解吧 回溯算法套路①子集型回溯【基础算法精讲 14】_哔哩哔哩_bilibili 完…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

篇章二 论坛系统——系统设计

目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...