javascript基础二十三:说说 JavaScript 中内存泄漏的几种情况

news2024/11/26 4:34:06

在这里插入图片描述
一、是什么

内存泄漏(Memory leak)是在计算机科学中,由于疏忽或错误造成程序未能释放已经不再使用的内存

并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,导致在释放该段内存之前就失去了对该段内存的控制,从而造成了内存的浪费

程序的运行需要内存。只要程序提出要求,操作系统或者运行时就必须供给内存

对于持续运行的服务进程,必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃
在这里插入图片描述
在C语言中,因为是手动管理内存,内存泄露是经常出现的事情。


char * buffer;
buffer = (char*) malloc(42);

// Do something with buffer

free(buffer);

上面是 C 语言代码,malloc方法用来申请内存,使用完毕之后,必须自己用free方法释放内存。

这很麻烦,所以大多数语言提供自动内存管理,减轻程序员的负担,这被称为"垃圾回收机制"

二、垃圾回收机制

Javascript 具有自动垃圾回收机制(GC:Garbage Collecation),也就是说,执行环境会负责管理代码执行过程中使用的内存

原理:垃圾收集器会定期(周期性)找出那些不在继续使用的变量,然后释放其内存

通常情况下有两种实现方式:

  • 标记清除
  • 引用计数

标记清除

JavaScript最常用的垃圾收回机制

当变量进入执行环境是,就标记这个变量为“进入环境“。进入环境的变量所占用的内存就不能释放,当变量离开环境时,则将其标记为“离开环境“

垃圾回收程序运行的时候,会标记内存中存储的所有变量。然后,它会将所有在上下文中的变量,以及被在上下文中的变量引用的变量的标记去掉

在此之后再被加上标记的变量就是待删除的了,原因是任何在上下文中的变量都访问不到它们了

随后垃圾回收程序做一次内存清理,销毁带标记的所有值并收回它们的内存

举个例子:

var m = 0,n = 19 // 把 m,n,add() 标记为进入环境。
add(m, n) // 把 a, b, c标记为进入环境。
console.log(n) // a,b,c标记为离开环境,等待垃圾回收。
function add(a, b) {
  a++
  var c = a + b
  return c
}

引用计数

语言引擎有一张"引用表",保存了内存里面所有的资源(通常是各种值)的引用次数。如果一个值的引用次数是0,就表示这个值不再用到了,因此可以将这块内存释放

如果一个值不再需要了,引用数却不为0,垃圾回收机制无法释放这块内存,从而导致内存泄漏

const arr = [1, 2, 3, 4];
console.log(‘hello world’);

上面代码中,数组[1, 2, 3, 4]是一个值,会占用内存。变量arr是仅有的对这个值的引用,因此引用次数为1。尽管后面的代码没有用到arr,它还是会持续占用内存

如果需要这块内存被垃圾回收机制释放,只需要设置如下:

arr = null

通过设置arr为null,就解除了对数组[1,2,3,4]的引用,引用次数变为 0,就被垃圾回收了

小结

有了垃圾回收机制,不代表不用关注内存泄露。那些很占空间的值,一旦不再用到,需要检查是否还存在对它们的引用。如果是的话,就必须手动解除引用

三、常见内存泄露情况

意外的全局变量

function foo(arg) {
    bar = "this is a hidden global variable";
}

另一种意外的全局变量可能由 this 创建:

function foo() {
    this.variable = "potential accidental global";
}
// foo 调用自己,this 指向了全局对象(window)
foo();

上述使用严格模式,可以避免意外的全局变量

定时器也常会造成内存泄露

var someResource = getData();
setInterval(function() {
    var node = document.getElementById('Node');
    if(node) {
        // 处理 node 和 someResource
        node.innerHTML = JSON.stringify(someResource));
    }
}, 1000);

如果id为Node的元素从DOM中移除,该定时器仍会存在,同时,因为回调函数中包含对someResource的引用,定时器外面的someResource也不会被释放

包括我们之前所说的闭包,维持函数内局部变量,使其得不到释放

function bindEvent() {
  var obj = document.createElement('XXX');
  var unused = function () {
    console.log(obj, '闭包内引用obj obj不会被释放');
  };
  obj = null; // 解决方法
}

没有清理对DOM元素的引用同样造成内存泄露

const refA = document.getElementById('refA');
document.body.removeChild(refA); // dom删除了
console.log(refA, 'refA'); // 但是还存在引用能console出整个div 没有被回收
refA = null;
console.log(refA, 'refA'); // 解除引用

包括使用事件监听addEventListener监听的时候,在不监听的情况下使用removeEventListener取消对事件监听

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

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

相关文章

【数学建模】期末样题(2021年真题)

一、(10分)某乳制品厂计划生产A、B、C三种酸奶。已知生产单位重量的A需要加工设备3小时,原料甲1千克,原料乙0.2千克;生产单位重量的B需要加工设备5小时,原料甲1千克,原料乙0.3千克;生…

若依之权限处理

若依之权限处理 若依前后端不分离版本使用的是shiro进行权限控制,本文主要是对shiro在若依中的使用进行分析。 RBAC权限模型 RBAC是指基于角色的访问控制。其基本思想是,对系统的各种权限不是直接授予具体的用户,而是在用户集合与权限集合…

【论文总结】Drifuzz: Harvesting Bugs in Device Drivers from Golden Seeds

Drifuzz:从金种子中收获设备驱动程序中的漏洞 摘要: 现代计算机中的外围硬件通常被认为是安全的且不带恶意,并且设备驱动程序以信任从硬件输入的方式实现。然而,最近的漏洞攻击(如Broadpwn)已经证明攻击者可以通过易受攻击的外围…

Map复习(JDK1.8)

首先考虑的问题任然是高并发的安全问题: HashMap是一个不安全的,多线程会导致数据不一致。 Hashtable是安全的,但是速度比较慢,只要是安全的就是一性能为代价换来的,加锁开锁需要时间,加锁是只能一个线程访…

服务注册与发现总结

文章目录 概要一、服务注册与发现技术要点1.1、服务注册/下线1.1.1、代理注册1.1.2、客户端注册 1.2、健康检查(续约)1.2.1、主动检测1.2.2、被动检测 1.3、服务发现1.3.1、代理发现1.3.2、客户端发现 1.4、服务变更通知1.4.1、主动通知1.4.2、被动通知 …

linux系统vim编辑器的使用

前言: 前面我们就说过在linux系统下一切都是文件,也可以说在日常使用linux系统过程中使用频率最高工具,基本没有之一,今天就来详情介绍一下我们在日常使用vim编辑器的过程中一些常见的指令,博主始终遵循好记心不如烂笔…

Excel排序

Excel排序 写在前面: Excel是我们最常用的办公工具之一,其中排序是最基础和最重要的一项,如下介绍了两种排序方式,有需要者可以参照这些步骤完成相关任务~ 一、排序方法1 使用Excel自带的排序功能,具体步骤如下&…

pandas菜鸟速学-series

一、pandas是什么 一个基于numpy的数据处理数据分析的工具。 特点: Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大…

重学SSE

概述 SSE(Server-Sent Events)是一种用于实现服务器主动向客户端推送数据的技术,也被称为“事件流”(Event Stream)。它基于 HTTP 协议,利用了其长连接特性,在客户端与服务器之间建立一条持久化…

暴力递归到动态规划(一)

⭐️前言⭐️ 动态规划是一个很难的模块,如果一道动态规划的题目直接去推出动态转移方程来解题,是很难的,所以应该先想出暴力解决的方法,再去用空间换时间优化,得出动态规划的解法。 🍉欢迎点赞 &#x1f…

【Java设计模式】—— 享元模式概述和示例

目录 概述享元模式的定义与特点享元模式的结构与实现1. 模式的结构2. 模式的理论实现 享元模式的应用实例代码实现 享元模式的应用场景享元模式的在实际工作中的应用参考文献 概述 在面向对象程序设计过程中,有时会面临要创建大量相同或相似对象实例的问题。创建那…

Linux命令学习之mkdir、rmdir和rm

这篇文章想要学习一下目录的创建(mkdir)、空目录的删除(rmdir)、非空目录的删除(rm)。 mkdir mkdir是新建目录的命令。man mkdir看一下mkdir的使用说明。 按q键退出帮助说明。 mkdir /learnwell在根目录…

贷款业务-贷款模式

参考文章 多流量模式下的系统设计- 呱说产品自营 互联网金融之信贷三部曲:贷中 导读 互联网的玩法,基本都是流量为王。网上也有种说法,互联网平台,最终都会走上金融业务,一般都是指贷款业务。 但是,做…

PLC信号发生器(博途SCL)

信号发生器的应用请参看下面的博客文章,在演示分析滤波器的作用时,我们需要对信号进行叠加处理。 博途PLC滤波指令 Filter_PT1、Filter_PT2、Filter_DT1详细使用说明(含Simulink+博途PLC仿真)_RXXW_Dor的博客-CSDN博客博途S7-1200/1500PLC的PID控制和详细使用说明,请参看…

计算机组成原理---第四章 指令系统习题详解版

(一)课内例题 4.1 4.2 具体分析,4.2 中, 因为只有一行:单字长 二地址:源寄存器、目标寄存器 操作码看OP(15-91) 然后按操作数的物理位置来区别RR型,RS型&#xf…

代码随想录训练营Day58| 739. 每日温度 496.下一个更大元素 I

目录 学习目标 学习内容 739. 每日温度 496.下一个更大元素 I 学习目标 739. 每日温度 496.下一个更大元素 I 学习内容 739. 每日温度 739. 每日温度 - 力扣(LeetCode)https://leetcode.cn/problems/daily-temperatures/ class Solution:def da…

Excel VBA编程

前两天我朋友找我帮忙,让给excel做个按钮功能,方便他们表格统计,我晚上研究了一下给他做出来了,这里记录一下入门操作和大概思路,具体怎么写VBA的代码我就不记录了,那玩意儿看教程去吧,也不是这…

【网络】socket套接字

1.理解IP 每台主机都有自己的IP地址,所以当数据从一台主机传输到另一台主机就需要IP地址。报头中就会包含源IP和目的IP。源IP地址:发送数据报那个主机的IP地址,目的IP地址:想发送到的那个主机的IP地址我们把数据从一台主机传递到…

C语言-const关键字

1.const 关键字 const 是 constant 的缩写,const 在实际编程中用得比较多,意思是“恒定不变的”,它是定义只读变量的关键字,或者说 const 是定义常变量的关键字。 (可读,不可写) const 可以修饰变量,数组&a…

光明区马田大围城市更新旧改项目--华润集团

【华润光明马田大围旧改一期项目基础信息】 项目开发商:华润集团 占 地 面 积:约110151㎡ 建 筑 面 积:待专规图 物 业 类 型:华润一期范围内的待拆迁物业 项 目 进 度:直接确权阶段,即将立项 【项目现…