浅谈内存泄漏

内存泄漏

概念

在JavaScript中,内存泄漏是指应用程序在不再需要使用某块内存时仍然保持对其的引用,导致内存不能被垃圾回收机制释放,最终导致内存占用过高,性能下降。

内存泄漏通常发生在以下情况:

  • 全局变量:全局变量会一直存在于内存中,即使在不需要时也无法被垃圾回收机制回收。
    未清理的定时器和回调函数:如果定时器或回调函数没有正确清理,它们将一直存在于内存中,即使它们已经完成或不再需要了。
  • DOM引用:当从DOM中删除元素时,如果仍然保持对该元素的引用,它将会在内存中留下无法释放的引用。
  • 闭包:如果函数创建了一个闭包(即函数内部引用了外部函数的变量),并且闭包没有在正确的时机释放,这将导致外部函数的变量一直无法被垃圾回收。

为了避免内存泄漏,可以采取以下措施:

  • 使用局部变量:在函数内部尽量使用局部变量而不是全局变量,以便在函数执行完毕后可以被垃圾回收。
  • 显式清理:在不再需要使用的定时器、回调函数和DOM引用时,手动清理它们,例如通过使用clearTimeout()清除定时器。
  • 解除闭包:在不需要使用闭包时,手动解除对外部函数变量的引用,以便垃圾回收机制可以释放内存。
  • 使用垃圾回收器:JavaScript具有自动的垃圾回收机制,可以自动释放不再需要的内存。通过确保代码的正确性和效率,可以帮助垃圾回收器更好地工作。

常见的内存泄漏

全局变量

  1. 意外的全局变量

    function leakFunction() {leakVar = 'test'
    }
    

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    解决方法use strict 启用严格模式,严格模式会阻止创建意外的全局变量

  2. 全局变量未释放

    全局变量未释放也会导致内存泄漏,可通过将变量置为null释放全局变量,避免内存泄漏

    // 未释放的全局变量
    var globalVar = 'Hello'function doSomething() {
    // ...
    }// 忘记释放全局变量// 可通过以下方式释放
    // globalVar = null
    // doSomething = null
    

闭包

闭包 中被访问的参数和变量不会被JavaScript的垃圾回收机制回收,会导致内存泄漏,可通过将变量置为null释放全局变量,避免内存泄漏

function createClosure() {var value = 'Hello'// 创建一个闭包函数function closureFunction() {console.log(value)}// 返回闭包函数return closureFunction
}// 创建闭包
var closure = createClosure()// 闭包持有外部变量的引用,可能导致内存泄漏// 可通过以下方式释放
// closure = null

定时器未清理

未清理定时器也会导致内存泄漏,可通过clearInterval清理定时器,避免内存泄漏

// 创建一个定时器
var timer = setInterval(function() {// 定时器回调函数// ...
}, 1000)// 定时器未清理// 可通过以下方式清理定时器
// clearInterval(timer)

清除页面dom元素不完全

  1. 清除页面dom元素时,dom元素绑定的事件未解绑
var element = document.getElementById('button')
var counter = 0
function onClick(event) {counter++element.innerHtml = 'clickTime ' + counter
}element.addEventListener('click', onClick)// 可通过以下方式清理
// element.removeEventListener('click', onClick)
// element.parentNode.removeChild(element)

循环引用

当两个或多个对象之间存在相互引用,并且没有被其他对象引用,就会发生循环引用,从而导致内存泄漏。这种情况可以通过在对象之间断开引用来避免

function createObject() {var obj1 = {}var obj2 = {}obj1.ref = obj2obj2.ref = obj1return obj1
}
var myObj = createObject()
// 这里无法回收 myObj 和 myObj.ref 所占用的内存空间,导致内存泄漏

常见的防止内存泄露方法

  1. 显式释放引用

    在不再使用变量、对象或函数时,手动将其引用置为null,以便垃圾回收器可以正确地回收内存

    var obj = {}// 使用obj// 当不再需要obj时,将其引用置为null
    obj = null
    
  2. 清除定时器

    在使用setInterval或setTimeout函数创建定时器时,应确保在不需要时及时清除定时器。可以使用clearInterval或clearTimeout函数来清除定时器

    var timer = setInterval(function() {
    // 定时器回调函数
    // ...// 当不再需要定时器时,清除定时器
    clearInterval(timer)
    }, 1000)
    
  3. 移除事件监听器

    在使用addEventListener函数添加事件监听器时,确保在不需要时移除事件监听器,以避免对象无法被垃圾回收。可以使用removeEventListener函数来移除事件监听器

    var button = document.createElement('button')function handleClick() {
    // 点击事件回调函数
    // ...// 当不再需要事件监听器时,移除事件监听器
    button.removeEventListener('click', handleClick)
    }// 添加点击事件监听器
    button.addEventListener('click', handleClick)
    
  4. 避免创建不必要的闭包

    闭包可以使函数保持对其定义时的作用域的引用,从而可能导致内存泄漏。尽量避免在不需要时创建不必要的闭包

    function createClosure() {var value = 'Hello'// 创建一个闭包函数function closureFunction() {console.log(value)}// 返回闭包函数return closureFunction
    }// 创建闭包
    var closure = createClosure()// 当不再需要闭包时,释放闭包引用
    closure = null
    

相关文档

【温故而知新】JavaScript中内存泄露有那几种

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

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

相关文章

【C++风云录】重塑旅游业:C++和可持续旅行的交汇点

跃升旅游行业:C库的革命性作用 前言 在21世纪,技术的发展已经渗透到每个角落,包括旅游行业。特别是在生态旅游和可持续旅行领域,新技术的引入正在改变着行业的未来。本文将重点介绍C如何被应用于这一领域。 欢迎订阅专栏&#x…

macos安装mysql一直卡在安装成功那个页面选项的解决办法

问题描述: 我安装的是比较新的版本8.0.37,安装过程中一直卡在安装那个选项上,且页面提示安装成功了,但就是死活不往下面的配置选项那一步走。 解决办法: 1.首先清理掉之前的mysql sudo rm -rf /usr/local/mysql2.然…

星期一的小小积累

3种方法教你将ArcGIS属性表转换为Excel表格 (baidu.com) ARCMAP属性表转换为Excel表格 主成分分析:spss分析方法-主成分分析_主成分分析法spss-CSDN博客

pthread_setname_np 线程设置名字 c++

pthread_setname_np_setpthreadname-CSDN博客 #define _GNU_SOURCE #include <pthread.h> int pthread_setname_np(pthread_t thread, const char *name); int pthread_getname_np(pthread_t thread, char *name, size_t len); pthread_setname_np(thread, name_s.c_s…

win11快速安装mysql数据库系统

win11快速安装mysql数据库系统 1、下载 1.1 打开官网 1.2 向下滚动页面 1.3 进入下载选项 1.4 下载8.0.4 LTS 1.5 开始下载 1.6 下载中 2、解压 大家注意&#xff0c;此时解压后目录是没有data目录的。 3、数据库初始化 3.1 管理员身份打开CMD 开始菜单上&#xff0c;输入…

代码随想录算法训练营第三十一天|455.分发饼干,376. 摆动序列,53. 最大子序和

455.分发饼干 优先把小饼干分给胃口值小的&#xff0c;或者是把大饼干分给胃口大的。 376. 摆动序列 class Solution { public:int wiggleMaxLength(vector<int>& nums) {if (nums.size() < 1) return nums.size();int curDiff 0; // 当前一对差值int preDiff …

Redis:功能特性和应用场景

文章目录 认识RedisRedis和MySQLRedis的场景Redis的设计 Redis的特性和优点Redis的应用场景Redis作为数据库Redis作为缓存Redis作为会话存储对象Redis作为消息队列 总结 本篇开始对于Redis进行正式介绍和学习 认识Redis 在开始Redis学习前&#xff0c;要先认识一下Redis Red…

详解绝对路径和相对路径的区别

绝对路径和相对路径是用于描述文件或目录在文件系统中位置的两种不同方式。 绝对路径&#xff08;Absolute Path&#xff09;是从文件系统的根目录开始的完整路径&#xff0c;可以唯一地确定一个文件或目录的位置。在不同的操作系统中&#xff0c;根目录的表示方式可能略有不同…

SpringSecurity安全过滤器工作原理

前面通过三篇文章&#xff0c;从底层代码的角度分析了SpringSecurity的初始化过程。 接下来我们就要具体看一下&#xff0c;Spring Security的安全过滤器初始化、装配好之后&#xff0c;到底是怎么工作的。 还是按图索骥 下面我们简单从底层源码分析一下&#xff0c;请求是怎…

【机器学习300问】90、怎么理解测试集、验证集必须和训练集来自于同一分布?

我写这篇文章是因为我自己在做一个手势识别项目的时候&#xff0c;所用的训练集是网上爬取的以及公开的数据集。但当我训练完成后使用我自己通过摄像头捕捉的实地拍摄的手势图片&#xff0c;得出的识别准确率非常的低&#xff01;这些图片可能在光照、背景、手势姿势等方面与通…

基于SpringBoot设计模式之创建型设计模式·工厂方法模式

文章目录 介绍开始架构图样例一定义工厂定义具体工厂&#xff08;上衣、下装&#xff09;定义产品定义具体生产产品&#xff08;上衣、下装&#xff09; 测试样例 总结优点缺点与抽象工厂不同点 介绍 在 Factory Method模式中&#xff0c;父类决定实例的生成方式&#xff0c;但…

图像/视频恢复和增强CodeFormer

github&#xff1a;https://github.com/sczhou/CodeFormer 尝试增强旧照片/修复人工智能艺术 面部修复 面部色彩增强和恢复 脸部修复

Python 机器学习 基础 之 监督学习 [ 核支持向量机 SVM ] 算法 的简单说明

Python 机器学习 基础 之 监督学习 [ 核支持向量机 SVM ] 算法 的简单说明 目录 Python 机器学习 基础 之 监督学习 [ 核支持向量机 SVM ] 算法 的简单说明 一、简单介绍 二、监督学习 算法 说明前的 数据集 说明 三、监督学习 之 核支持向量机 1、线性模型与非线性特征 …

汇编语言入门:探索 x86 架构

目录 前言 1. x86 语言 x86 架构简介 x86 架构的特点 x86 架构的演变 x86 架构的应用 2. 常用汇编指令集 3. 寻址方式 结语 前言 汇编语言是一种低级编程语言&#xff0c;直接面向计算机的硬件架构。在计算机科学中&#xff0c;了解汇编语言是非常重要的&#xff0c;因…

探索Java中的利器:ThreadLocal

在日常的Java开发中&#xff0c;我们经常会遇到多线程并发访问共享资源的情况&#xff0c;而这时候线程安全就成了我们需要重点考虑的问题之一。幸运的是&#xff0c;Java提供了一种非常巧妙的机制来解决这个问题&#xff0c;那就是 ThreadLocal。 什么是ThreadLocal&#xff…

基于网络爬虫技术的网络新闻分析(二)

目录 2 系统需求分析 2.1 系统需求概述 2.2 系统需求分析 2.2.1 系统功能要求 2.2.2 系统IPO图 2.2 系统非功能性需求分析 3 系统概要设计 3.1 设计约束 3.1.1 需求约束 3.1.2 设计策略 3.1.3 技术实现 3.3 模块结构 3.3.1 模块结构图 3.3.2 系统层次图 3.3.3…

JumpServer堡垒机应用(v3.10.8) 下

目录 JumpServer堡垒机简单式部署与管理(v3.10.8) 上-CSDN博客 一. 资产管理 1.1创建资产 1.2 给资产主机创建用户 1.2.1 普通账户&#xff1a; 1.2.2 特权账户&#xff1a; 1.2.3 创建用户 二. 命令过滤 2.1 创建命令组 2.2 创建命令过滤 ​编辑 三. 创建资产授权 …

在另外一个页面,让另外一个页面弹框显示操作(调佣公共的弹框)vue

大概意思是&#xff0c;登录弹框在另外一个页面中&#xff0c;而当前页面不存在&#xff0c;在当前页面中判断如果token不存在&#xff0c;就弹框出登录的弹框 最后一行 window.location.href … 如果当前用户已登录&#xff0c;则执行后续操作(注意此处&#xff0c;可不要)

2024中国应急(消防)品牌巡展西安站成功召开!惊喜不断

消防品牌巡展西安站 5月10日&#xff0c;由中国安全产业协会指导&#xff0c;中国安全产业协会应急创新分会、应急救援产业网联合主办&#xff0c;陕西消防协会协办的“一切为了安全”2024年中国应急(消防)品牌巡展-西安站成功举办。该巡展旨在展示中国应急&#xff08;消防&am…

ADS使用记录之使用RFPro进行版图联合仿真

ADS使用记录之使用RFPro进行版图联合仿真 在ADS中&#xff0c;我们往往使用EM仿真来明确电路的实际性能&#xff0c;但是常规的方法我们只会得到S参数&#xff0c;对于场还有电路的电流分布往往不进行检查。但是在实际中&#xff0c;观察场和电流分布是非常有意义的&#xff0…