彻底消除 JavaScript 中的内存泄漏
垃圾回收语言中内存泄漏的主要原因是不必要的引用。为了理解内存泄漏,让我们看看内存释放(垃圾回收)是如何工作的。
标记-清除算法 −此算法将“不再需要对象”的定义简化为“对象不可达”。此算法假设知道一组称为根的对象。在 JavaScript 中,根是全局对象。垃圾回收器会定期从这些根开始,递归查找从这些根引用的所有对象。从根开始,垃圾回收器将找到所有可达对象,并收集所有不可达对象。
内存泄漏的类型
1. 全局变量(未声明/意外)
在 JS 中,如果您没有指定声明关键字(let、var、const),则可能会意外地声明一个全局变量。JS 向外查找作用域,直到到达全局作用域,如果它在任何作用域中都没有找到该变量,它就会创建一个全局变量。
示例
function test() {
a = [1, 2, 3]
}
test()
// a was initialized without declaration using a keyword and is now in the global scope.
console.log(a)输出
[1, 2, 3]
这种行为会导致内存泄漏,因为变量不知不觉地存在于全局作用域中,并且除非程序结束,否则不会被释放。这可以通过使用声明关键字来解决。
2. 闭包
如果在外部函数中声明的变量会自动提供给嵌套的内部函数,即使在嵌套函数中未使用/引用该变量,它也会继续保留在内存中,则会在闭包中发生内存泄漏。
3. 脱离 DOM/DOM 外部引用
DOM 是一个双向链表树,对树中任何节点的引用都将阻止整个树进行垃圾回收。脱离 DOM 或 DOM 外部引用意味着已从 DOM 中移除但通过 JS 保留在内存中的节点。这意味着只要在任何地方仍然存在对变量或对象的引用,即使该对象已从 DOM 中移除,也不会进行垃圾回收。一旦完成 DOM 的一部分,务必从 JS 中删除引用。
4. 事件监听器
addEventListener() 方法将事件处理程序附加到元素,并且可以将多个事件处理程序添加到单个元素。如果 DOM 元素及其事件监听器的生命周期不同,则可能会导致内存泄漏。
广告
数据结构
网络
关系数据库管理系统 (RDBMS)
操作系统
Java
iOS
HTML
CSS
Android
Python
C 编程
C++
C#
MongoDB
MySQL
Javascript
PHP