JS【详解】内存泄漏(含泄漏场景、避免方案、检测方法),垃圾回收 GC (含引用计数、标记清除、标记整理、分代式垃圾回收)
内存泄漏
在执行一个长期运行的应用程序时,应用程序分配的内存没有被释放,导致可用内存逐渐减少,最终可能导致浏览器崩溃或者应用性能严重下降的情况,即 JS 内存泄漏
可能导致内存泄漏的场景
- 不断创建全局变量
- 未及时清理的闭包:如果闭包中引用了外部的变量,而这个变量又没有被及时释放,就可能发生内存泄漏。
- DOM元素的引用:如果一个DOM元素被保存在一个JavaScript变量中,但是页面上该DOM元素被移除,这个变量仍然引用着这个DOM元素,导致它无法被垃圾回收。
- 事件监听器:如果一个DOM元素添加了事件监听器,但在移除该元素之前没有移除事件监听器,则可能发生内存泄漏。
- 循环引用:两个对象相互引用,导致它们不能被垃圾回收。(现代浏览器改用标记清除的垃圾回收机制,已解决了此问题)
vue 中内存泄漏的场景
组件销毁时未清除全局变量的引用、函数引用、全局事件、自定义事件、定时器。
// 全局变量引用vue实例上的响应式变量
window.list = this.list
// 全局变量引用vue实例上的函数
window.copy = this.copy
如何避免内存泄漏?
- 避免创建全局变量。
- 使用严格模式或者let/const声明变量。
- 及时解除DOM元素的引用。
- 在移除DOM元素之前,移除相关的事件监听器。
- 使用弱引用或者引用计数来处理循环引用的问题。(如使用 WeakMap 和WeakSet)
- 使用工具或者浏览器自带的开发者工具检测和分析内存使用情况,找出潜在的内存泄漏。
- 编写单元测试以确保内存的正确释放。
- 使用try/catch/finally来确保资源在异常发生时也能被正确释放。
- 定期进行垃圾回收(例如在JavaScript中可以使用window.gc()来强制进行垃圾回收,但这不是标准方法,并且不建议在生产环境中使用)。
检测 JS 内存泄漏的方法
可使用浏览器自带的开发者工具

上图中,HEAP值随时间一直上升,即发生了内存泄漏
正常的内存应该如下图(每隔一段时间,就会进行垃圾回收下降)

垃圾回收 GC
GC 是垃圾回收(Garbage Collection)的缩写,是由 JavaScript 引擎自动执行的自动内存管理机制,用于检测和清除不再使用的数据,以释放内存空间。
垃圾回收的目的是减少内存泄漏和提高程序的性能。
JS 垃圾回收的算法
引用计数(之前)
通过跟踪每个对象被引用的次数来确定对象是否为垃圾。
逻辑
- 当一个对象被创建时,其引用计数器初始化为1。
- 当该对象被其他对象引用时,引用计数器加1。
- 当该对象不再被其他对象引用时,引用计数器减1。
- 当引用计数器减至0时,意味着该对象不再被引用,可以被垃圾收集器回收。
// 创建一个对象
let obj = { name: "test" };
// 创建一个引用指向对象
let ref1 = obj;//引用计数+1 1
// 创建另一个引用指向对象
let ref2 = obj;//引用计数+1 2
// 引用失效
ref1 = null;//引用计数-1 1
ref2 = null;//引用计数-1 0
// 引用计数为0,对象可以被回收
优点
- 实时回收:在对象不再被引用时立即回收,不需要等待垃圾收集器的运行。这可以减少内存占用和提高程序的性能。
- 简单高效:实现起来相对容易,不需要复杂的算法和数据结构。
缺点
- 两个或多个对象相互引用时,无法被回收,导致内存泄漏
- 引用计数需要占用额外的内存空间,而且每次添加、删除引用都需要更新计数,增加了额外的开销。
标记清除(现代)
通过标记不再使用的对象,然后清除这些对象的内存空间,以便后续的内存分配使用。
逻辑
- 在标记阶段,垃圾回收器会对内存中的所有对象进行遍历,从根对象开始(通常是全局对象)递归地遍历对象的引用关系。对于每个被访问到的对象,垃圾回收器会给它打上标记,表示该对象是可达的,即不是垃圾。
- 在清除阶段,垃圾回收器会遍历整个内存,对于没有标记的对象,即被判定为垃圾的对象,会被立即回收,释放内存空间。
优点
- 简单有效:算法相对简单,容易实现
- 可清除循环引用
缺点
- 会暂停程序的执行,进行垃圾回收操作。当堆中对象较多时,可能会导致明显的停顿,影响用户体验。
- 会在回收过程中产生大量的不连续的、碎片化的内存空间。这可能导致后续的内存分配难以找到足够大的连续内存块,从而使得内存的利用率降低。
标记整理(优化)
在标记清除的基础上,增加了整理
逻辑
- 在标记阶段,标记活动对象
- 在整理阶段,将内存中的活动对象移动到一端,使得空闲空间连续,并且没有碎片化。
- 在清除阶段,清除垃圾,回收内存
优点
- 解决了标记-清除算法产生的碎片化问题,使得内存空间得到更好的利用,减少了空间的浪费。
缺点
- 会暂停程序的执行,进行垃圾回收操作。当堆中对象较多时,可能会导致明显的停顿,影响用户体验。
V8 引擎的垃圾回收策略
V8是一种由Google开发的用于执行JavaScript 的开源引擎,用于浏览器和Node.js
分代式垃圾回收
将内存划分为新生代(Young Generation)和老生代(Old Generation)两个代:
- 新生代:存放的是存活时间较短的对象(经过一次垃圾回收后,就被释放回收掉),采用了基于Scavenge算法的快速垃圾回收策略,通过将内存分为两个半空间来进行垃圾回收,优化了对象的分配和回收过程。
- 老生代:存放的是存活时间较长的对象(经过多次垃圾回收后仍存在),采用了基于标记-整理-清除算法的全垃圾回收策略,通过对整个堆进行标记和整理,以减少内存的碎片化,提高内存利用率。
更多详情可参考
https://zhuanlan.zhihu.com/p/689678104
相关文章:
JS【详解】内存泄漏(含泄漏场景、避免方案、检测方法),垃圾回收 GC (含引用计数、标记清除、标记整理、分代式垃圾回收)
内存泄漏 在执行一个长期运行的应用程序时,应用程序分配的内存没有被释放,导致可用内存逐渐减少,最终可能导致浏览器崩溃或者应用性能严重下降的情况,即 JS 内存泄漏 可能导致内存泄漏的场景 不断创建全局变量未及时清理的闭包&…...
第三期书生大模型实战营之Llamaindex RAG实践
基础任务 任务要求:基于 LlamaIndex 构建自己的 RAG 知识库,寻找一个问题 A 在使用 LlamaIndex 之前InternLM2-Chat-1.8B模型不会回答,借助 LlamaIndex 后 InternLM2-Chat-1.8B 模型具备回答 A 的能力,截图保存。 streamlit界面…...
【从0到1进阶Redis】Jedis 理解事务
笔记内容来自B站博主《遇见狂神说》:Redis视频链接 小伙伴们可以熟悉一下本专栏的 Redis 文章,可以更好地理解 正常操作 package oldfe.study;import com.alibaba.fastjson.JSONObject; import redis.clients.jedis.Jedis; import redis.clients.jedis.T…...
MySQL之Lost connection to MySQL server during query复现测试
测试Lost connection to MySQL server during query复现条件 环境报错信息复现测试方式一方式二 环境 Python: 3.8/3.9 Mysql: 5.x 报错信息 File "/Users/xxx/lib/python3.9/site-packages/sqlalchemy/dialects/mysql/base.py", line 2509, in do_rollbackdbapi_con…...
中国AI大模型场景探索及产业应用调研报告
AI大模型发展态势 定义 AI大模型是指在机器学习和深度学习领域中,采用大规模参数(至少在一亿个以上)的神经网络模型,AI大模型在训练过程中需要使用大量的算力和高质量的数据资源。 产业规模 2023年,中国大模型市场规模为147亿。结合《202…...
Linux--shell脚本语言—/—<1>
一、shell简介 Shell是一种程序设计语言。作为命令语言,它交互式解释和执行用户输入的命令或者自动地解释和执行预先设定好的一连串的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构&am…...
【java框架开发技术点】通过反射机制调用类中的私有或受保护的方法
示例 假设我们有一个类 ExampleClass,其中有一个私有方法 privateMethod: public class ExampleClass {private void privateMethod(String message) {System.out.println("Private method called with message: " + message);} }我们可以使用上述代码来调用这个…...
你知道这些鼎鼎大名的Java底层核心公司吗
在讨论Java虚拟机——JVM的时候,有几个知名的,不得不提到的JVM的产品和公司。 一、Oracle HotSpot:这是由Sun公司开发的虚拟机。它由最初的Classic VM开始,到推出崭露头角的Exact VM的虚拟机,是现代化高性能虚拟机的最…...
C++入门级文章
一、一个用于查询C标准库内函数、操作符等的链接 https://legacy.cplusplus.com/reference/ 声明:该文档并非官方文档,但其具有易于查询和使用的优势,足够日常使用。 二、C的第一个程序 1、C语言中的语法在C中仍旧适用,首先我们来…...
modelsim仿真quartus IP
开发环境:quartus prime pro 20;modelsim se-64 10.6d 1. 生成Altera的IP库 使用quartus生成IP库,需要使用Simulation Library Compiler(Tools->Launch Simulation Library Compiler) 如下图操作,选择…...
PCB设计经验——布线原则
1.连线精简——避免直角布线 导线也应看作一种元器件,有自己的电阻,电感,电容 PCB走线在直角转弯的地方,信号前后部分相互影响,导致分布电容增加,对信号上升沿和下降沿有延缓影响。从阻抗的角度来说&#…...
C++进阶:设计模式___适配器模式
前言 在C的基础语法的学习后,更进一步为应用场景多写代码.其中设计模式是有较大应用空间. 引入 原本在写容器中适配器类有关的帖子,发现适配模式需要先了解,于是试着先写篇和适配器模式相关的帖子 理解什么是适配器类,需要知道什么是适配器模式.适配器模式是设计模式的一种.笔…...
“八股文“在现代编程面试中的角色重塑:助力、阻力还是桥梁?
🌈所属专栏:【其它】✨作者主页: Mr.Zwq✔️个人简介:一个正在努力学技术的Python领域创作者,擅长爬虫,逆向,全栈方向,专注基础和实战分享,欢迎咨询! 您的点…...
Android 安装应用-浏览阶段
应用安装的浏览阶段主要是由PackageManagerService类中的scanPackageNewLI()实现的,看一下它的代码: // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting// the results / removing app data needs to be move…...
JavaEE 初阶(10)——多线程8之“单例模式”
目录 一. 设计模式 二. 单例模式 2.1 饿汉模式 2.2 懒汉模式 a. 加锁synchronized b. 双重if判定 c. volatile关键字(双重检查锁定) 一. 设计模式 设计模式是在软件工程中解决常见问题的经典解决方案。针对一些特定场景给出的一些比较好的解决…...
Javascript常见设计模式
JS设计模式学习【待吸收】-CSDN博客 JavaScript 中的设计模式是用来解决常见问题的最佳实践方案。这些模式有助于创建可重用、易于理解和维护的代码。下面列出了一些常见的 JavaScript 设计模式及其代码示例。 1. 单例模式(Singleton) 单例模式确保一…...
JavaFX布局-SplitPane
JavaFX布局-SplitPane 常用属性orientationpaddingdividerPositionsdisable 实现方式Java实现fxml实现 一个拆分至少两个区域的容器支持水平、垂直布局可以拖动区域的大小初始化大小通过比例设置[0,1] 常用属性 orientation 排列方式,Orientation.VERTICAL、Orien…...
2.MySQL库的操作
创建数据库 创建数据库的代码: CREATE DATABASE [IF NOT EXISTS] db_name [create_specification [,create_specification] ...];create_specification:[DEFAULT] CHARACTER SET charset_name[DEFAULT] COLLATE collation_name 说明: 大写的表示关键…...
如何学习计算机
不要只盯着计算机语言学习,你现在已经学习了C语言和Java,暑假又规划学习Python,最后你掌握的就是计算机语言包而已。 2. 建议你找一门想要深挖的语言,沿着这个方向继续往后学习知识就行。计算机语言是学不完的,而未来就…...
Spring MVC 快速入门指南及实战演示
1、SpringMVC简介 1.1 背景 Servlet属于web层开发技术,技术特点: 1. 每个请求都需要创建一个Servlet进行处理 2. 创建Servlet存在重复操作 3. 代码灵活性低,开发效率低 是否有技术方案可以解决以上问题? 1.2 SpringMVC概述 Sp…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
在四层代理中还原真实客户端ngx_stream_realip_module
一、模块原理与价值 PROXY Protocol 回溯 第三方负载均衡(如 HAProxy、AWS NLB、阿里 SLB)发起上游连接时,将真实客户端 IP/Port 写入 PROXY Protocol v1/v2 头。Stream 层接收到头部后,ngx_stream_realip_module 从中提取原始信息…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
C++ 设计模式 《小明的奶茶加料风波》
👨🎓 模式名称:装饰器模式(Decorator Pattern) 👦 小明最近上线了校园奶茶配送功能,业务火爆,大家都在加料: 有的同学要加波霸 🟤,有的要加椰果…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
【FTP】ftp文件传输会丢包吗?批量几百个文件传输,有一些文件没有传输完整,如何解决?
FTP(File Transfer Protocol)本身是一个基于 TCP 的协议,理论上不会丢包。但 FTP 文件传输过程中仍可能出现文件不完整、丢失或损坏的情况,主要原因包括: ✅ 一、FTP传输可能“丢包”或文件不完整的原因 原因描述网络…...
论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...
链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
