开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第32天,点击查看活动详情
内存泄漏,是指当内存不再被应用程序使用的时候,由于某种原因,这块内存没有被释放现象
在编程语言中,基本都会涉及到内存泄漏的问题。在程序中编写指令,定义变量等,系统就会分配内存,当我们不再使用这个数据,或者关闭程序时,就需要释放内存。当内存没有及时释放,就会产生内存泄漏。
情况一:
在 JS 中,未进行声明的变量在引用时,会在全局对象内创建一个新变量。(全局对象就是浏览器中的 window)。
function say() {
msg = 'hello';
}
注:上述代码中的语句,等同于 window.msg = 'hello';
关闭页面前,全局变量会持续存留在内存中,
解决方案:
在 JS 文件开头添加 use strict 严格模式。这样可以防止意外的全局变量,在使用完之后,可以再将其赋值为 null
情况二:
除此之外,setTimeout 和 setInterval 也是可能或造成内存泄漏的原因
var serverData = loadData();
setInterval(function() {
var renderer = document.getElementById('renderer');
if(renderer) {
renderer.innerHTML = JSON.stringify(serverData);
}
}, 5000);
情况三:
JS 中闭包表示一个可以访问外部函数变量的内部函数。以下代码形成闭包可能出现泄漏内存的问题,函数执行完毕,但是内存没有被回收。下面这段代码创建了闭包,即使有些代码声明了但是没有使用,依旧可以在外部被访问
var a = null;
var func1 = function () {
var b = a;
var func1 = function () {
if (b)
console.log("111");
};
a = {
myArr: new Array(100).join('*'),
myFunc: function() {
console.log("222");
}
}
}
}
setInterval(func1, 1000);
情况四:DOM 引用
如果每行 DOM 的引用存储在字典或数组中,就会保留一个 DOM 元素的两份引用:一个引用在 DOM 中,另一个引用在字典中。只有在DOM和另外的引用上同时移除了,才可以被 JS 的回收机制回收
let obj = {
image: document.getElementById('image'),
};
function setData() {
obj.image.src = './imag1.png';
}
function remove() {
document.body.removeChild(document.getElementById('image'));
}
所以综合上面的几种情况,解决内存泄漏也要从:全局变量、setTimeout 和 setInterval 、闭包、DOM 引用这几点入手来避免或者解决。