这篇文章主要讲讲JS中有哪些操作会导致内存泄漏。首先我理解的内存泄漏是由于代码书写不当,导致部分变量无法被JS中的垃圾回收机制清除,而永久的遗留在了内存中,从而导致内存占用变大,这就是内存泄漏。
而JS的垃圾回收机制有分有两种算法
- 标记清除
- 引用计数
导致内存泄漏的几种情况
闭包
我认为闭包是极为容易的导致内存泄漏,而且不易被发现,如果对闭包概念不了解的小伙伴可以看我另一篇文章:闭包 这里看一下代码
function f1(){
let a = 1;
function f2(){
console.log(a++)
}
return f2
}
let fn = f1();
fn();//1
fn();//2
//....
可以看到,这里调用fn以后,输出的是不一样的结果,这说明了f1的局部变量a一直存在于内存中,没有在调用完f1以后被立刻清除,这是由于f2中存在对外层变量a的引用,因此外层作用域环境是一直都存在的,不会被回收,所以这里就造成了内存泄漏,如果是一个数据量更大的变量,那后果将不可设想。
解决方法: 将被循环引用的变量设为null即可
dom元素
当我们移除页面中的dom元素时,对dom元素的引用可能还没移除,也会导致内存泄漏
let button = document.getElementById('button');
button.click();
document.body.removeChild(button)
虽然在body中移除了这个dom,但内存中仍然保留了对这个dom的引用,如果dom中的数据量比较大,也会占用很大的内存,所以在引用完dom后,要手动将其设置为null
循环引用
在引用计数策略下,会造成内存泄漏
function fn(){
let a = {};
let b = {};
a.name = b;
b.name = a;
}
fn();
在调用完fn后,a和b的引用次数都是2,因此不会被回收,造成内存泄漏
计时器
其实计时器产生的内存泄漏和闭包有几分相似,也是占用着外层作用域不释放而造成的
var someResource = getData();//大量数据
setInterval(function() {
var node = document.getElementById('Node');
if(node) {
node.innerHTML = JSON.stringify(someResource));
}
}, 1000);
定时器内部的回调函数包含对外部数据的引用,外部变量得不到释放,会造成内存泄漏,所以定时器用完一定要记得手动清除(clearInterval)
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!