搞懂内存泄漏到底是什么,造成内存泄漏的常见原因以及对应的解决方法

📝 ✏️ 📌
搞懂内存泄漏到底是什么,造成内存泄漏的常见原因以及对应的解决方法

目录

1.内存泄漏到底是什么

2.造成内存泄漏的常见原因/情况有哪些,相应的解决方法

1.闭包引起的内存泄漏

2.未销毁事件监听器

3.忘记清除的定时器或者回调

4.循环引用

5.意外创建的全局变量(直接使用未声明的变量)

1.内存泄漏到底是什么

内存泄漏是指应用程序中的内存被错误地分配和释放,导致无法再次使用的内存堆积。这通常是由于开发者忘记释放不再使用的对象或数据而引起的。 内存泄漏会导致内存消耗过多,最终使应用程序性能下降,甚至崩溃。

2.造成内存泄漏的常见原因/情况有哪些,相应的解决方法

1.闭包引起的内存泄漏

闭包可以读取函数内部的变量,然后让这些变量始终保存在内存中。如果在使用结束后没有将局部变量清除,就可能导致内存泄露。

引申: 闭包的定义:闭包就是在一个函数A内部定义一个新的函数B,并且这个新函数B,调用了在函数A内定义的变量,并且在函数A外部被调用,这就形成了闭包。

//闭包示例代码

function fn () {

var a = "这是一个变量a";

return function () {

console.log(a); //内部函数使用外部变量

};

}

解决方法: 将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中。

//将事件处理函数定义在外部,解除闭包,或者在定义事件处理函数的外部函数中

function fun(a) {

console.log(a)

}

for (var i = 0; i < 10; i++) {

fun(i)

}

fun = null

2.未销毁事件监听器

当你在DOM元素上添加事件监听器时,如果不手动删除它们,即使元素被销毁了,它们也将一直存在于内存中

// 为元素添加事件监听器

const button = document.getElementById('myButton');

button.addEventListener('click', () => {

// 处理点击事件

});

解决方法:

在组件/元素卸载或不再需要时,手动删除事件监听器。

// 在组件/元素卸载或不再需要时,手动删除事件监听器

const button = document.getElementById('myButton');

const handleClick = () => {

// 处理点击事件

};

button.addEventListener('click', handleClick);

// 移除事件监听器

button.removeEventListener('click', handleClick);

3.忘记清除的定时器或者回调

定时器中有 dom 的引用,即使 dom 删除了,但是定时器还在,所以内存中还是有这个 dom

var serverData = loadData()

let timer = setInterval(function () { //定时器timer

var renderer = document.getElementById('renderer')

if (renderer) {

renderer.innerHTML = JSON.stringify(serverData)

}

}, 5000)

// 观察者模式

var button = document.getElementById('myButton')

function onClick(element) {

element.innerHTMl = "这是一个插入内容"

}

btn.addEventListener('click', onClick)

解决方法:

手动删除定时器和 dom。

clearInterval(timer);

4.循环引用

当两个或多个对象相互引用时,并且没有任何引用指向它们之中的任何一个时,它们将无法被垃圾回收

// 循环引用

function createObjects() {

const obj1 = {};

const obj2 = {};

obj1.ref = obj2;

obj2.ref = obj1;

}

createObjects();

解决方法:

避免循环引用,或者当不再需要这些引用时手动解除它们。

// 手动解除

function createObjects() {

const obj1 = {};

const obj2 = {};

obj1.ref = obj2;

obj2.ref = obj1;

// 不再需要 obj1 和 obj2 的引用时,将它们设为 null

obj1.ref = null;

obj2.ref = null;

}

createObjects();

5.意外创建的全局变量(直接使用未声明的变量)

由于 js 对未声明变量的处理方式是在全局对象上创建该变量的引用,它在窗口关闭或重新刷新页面之前都不会被释放,如果未声明的变量缓存大量的数据,就会导致内存泄露

// a并未声明但直接使用(JS在非严格模式下)

function fn() {

a = 'a是一个全局变量'

}

fn()

//或使用this定义的变量,在浏览器中,全局对象就是 window 对象

// function fn() {

// this.a = 'a是一个全局变量'

// }

// fn()

解决方法:

尽量在定义变量之后再使用,或者使用JS严格模式(在 JavaScript 文件头部或者函数的顶部加上 use strict)。

(欢迎补充!!!!)

🔗 相关推荐

✨ 💡 🎯
OA办公系统多少钱一套?5款OA办公系统价格详细对比
魔兽世界木喉要塞声望怎么刷快 快速冲声望攻略及用处详解
【科普】悦趣教你认识最常见的管弦乐团乐器 | 悦趣音乐中心