原文: http://www.pc6.com/infoview/Article_48896.html
以下是常见的几种javascript内存泄露的情况:
一、循环引用:
我们可以看到,myGlobalObject指向了一个DOM对象,而这个DOM对象的一个属性又指向了myGlobalObject,循环引用出现,内存泄露,其原理如下:
解决方案很简单,在确保属性不再使用后,加入以下代码就可以了:
说起来容易,不过当我们程序非常复杂的时候,发现和修改就没有这么容易了.
二、闭包(Closures)
仍然先看一段代码:
闭包的一个内部方法赋给了element对象,产生了一个作用域的循环引用,从而造成内存泄露.其原理图如下:
解决方案如下,在确定事件不再使用后,解除事件的绑定:
通常情况下,常用的js框架都帮我们解决了这个问题,不需要我们自己处理,这也是使用框架的一个好处.
三、Cross-Page-Leaks
仍然先看一个例子:
LeakMemory和CleanMemory这两段函数的唯一区别就在于他们的代码的循序,从代码上看,两段代码的逻辑都没有错.
但LeakMemory却会造成泄露.原因是LeakMemory()会先建立起parentDiv和childDiv之间的连接,这时候,为了让 childDiv能够获知parentDiv的信息,因此IE需要先建立一个临时的scope对象.而后parentDiv建立了和 hostElement对象的联系,parentDiv和childDiv直接使用页面document的scope.可惜的是,IE不会释放刚才那个临时的scope对象的内存空间,直到我们跳转页面,这块空间才能被释放.而CleanMemory函数不同,他先把parentDiv和 hostElement建立联系,而后再把childDiv和parentDiv建立联系,这个过程不需要单独建立临时的scope,只要直接使用页面 document的scope就可以了, 所以也就不会造成内存泄露了.但是,需要特别说明一下,如果LeakMemory方法里面,创建的div对象上不绑定script事件,那么也不会有泄漏,这个可以理解为ie的bug,大家记住就可以了,不需要过分深究.其原理如下:
四、Pseudo-Leaks:
同样可以理解为ie的bug的一种泄露:
没什么特别的好解释,记住就可以了.
关于这四种泄漏的具体描述,还是请各位参照原文:http://msdn.microsoft.com/en-us/library/Bb250448
以上是几种主要的泄露,当然,除此之外,网上还有一些其他的讨论,比如var str = "lalala";alert(str.length);这个简单的语句也会造成内存泄露,原因是类型转换的时候,ie生成了一个临时对象,这个临时对象被泄漏了.类似情况还有很多,大家有兴趣可以自己去搜集整理.
最后说一下,只要ie6还健在,作为前端开发人员,就不能逃避这些问题,当然,也不必过分深究,比如闭包的情况就比较难避免,就像我一开始说的,毕竟,javascript造成的内存泄露不是程序和项目的瓶颈,我们需要在各方面进行权衡.