javascript常见内存泄露

本文详细介绍了JavaScript中常见的内存泄漏情况,包括全局变量、闭包、子元素引用、定时器及循环引用等引起的内存泄漏,并提供了相应的解决办法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、全局变量引起的内存泄漏

function func(){
  lmw = 123456 //lmw是全局变量,不会被释放   
}

 二、闭包引起的内存泄漏

function func(){
  var lmw = 123456;//闭包环境,不会被释放
  function lmw2(){
    //就算是一个空函数,也不会释放
  }
  return lmw2 //被暴露在外界,随时可能被引用
}

 三、子元素存在引用引起的内存泄漏

var select = document.querySelector;
var treeRef = select('#tree');

var leafRef = select('#leaf');   //在COM树中leafRef是treeFre的一个子结点

select('body').removeChild(treeRef);//#tree不能被回收入,因为treeRef还在

解决方法:

treeRef = null;//tree还不能被回收,因为叶子结果leafRef还在
leafRef = null;//现在#tree可以被释放了

四、定时器泄露

var  timer=null
for(var  i=0;i<5;i++){
    var funcObj = {
        "handle":function(){
            var _this = this;
            timer = setTimeout(function(){
                console.log(_this)
                _this.handle()
            },9000)
        }
    }
}
funcObj.handle()
funcObj = null //只是改变funcObj存储在栈里的引用地址,堆里保存的真实对象不会被释放,定时器还在引用
console.log(funcObj)

真正的释放还要清除定时器,再把funcObj = null

clearTimeout(timer)
funcObj = null
console.log(funcObj)

五、循环引用

function fn() {
 var a = {};
 var b = {};
 a.pro = b;
 b.pro = a;
}
 
fn();
以上代码a和b的引用次数都是2,fn()执行完毕后,两个对象都已经离开环境,在标记清除方式下是没有问题的,但是在引用计数策略下,因为a和b的引用次数不为0,所以不会被垃圾回收器回收内存,如果fn函数被大量调用,就会造成内存泄露。在IE7与IE8上,内存直线上升。
IE中有一部分对象并不是原生js对象。比如,DOM和BOM中的对象就是使用C++以COM对象的形式实现的,而COM对象的垃圾回收机制采用的就是引用计数策略。因此,即使IE的js引擎采用标记清除策略来实现,但js访问的COM对象依然是基于引用计数策略的。
换句话说,只要在老IE中涉及COM对象,就会存在循环引用的问题
var element = document.getElementById("some_element");
var myObject = new Object();
myObject.e = element;
element.o = myObject;

这个例子在一个DOM元素(element)与一个原生js对象(myObject)之间创建了循环引用。其中,变量myObject有一个名为e的属性指向element对象;而变量element也有一个属性名为o回指myObject。由于存在这个循环引用,即使例子中的DOM从页面中移除,它也永远不会被回收。
解决方法:
myObject.e= null;
element.o = null;
再来看一个在日常开发中容易犯错的例子:
window.onload=function outerFunction(){
 var obj = document.getElementById("element");
 obj.onclick=function innerFunction(){};
};
这段代码看起来没什么问题,但是obj引用了document.getElementById(“element”),而document.getElementById(“element”)的onclick方法会引用外部环境中的变量,自然也包括obj。
解决方法:
window.onload=function outerFunction(){
 var obj = document.getElementById("element");
 obj.onclick=function innerFunction(){};
 obj=null;
};

将变量设置为null意味着切断变量与它此前引用的值之间的连接。当垃圾回收器下次运行时,就会删除这些值并回收它们占用的内存。
在上面描述的循环引用例子,还可以理解成闭包循环引用导致的内存泄漏
当对DOM元素进行其他操作时,仍然要处处留心。只要是将JavaScript对象指定给DOM元素,就可能在旧版本IE中导致内存泄漏。jQuery只是有助于减少发生这种情况的可能性

注意:IE9+并不存在循环引用导致Dom内存泄露问题

 

转载于:https://www.cnblogs.com/liumingwang/p/6769774.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值