学习笔记,先挖坑,以后慢慢填
一、定义
内存泄漏:浏览器中使用的内存资源得不到释放,失去对该内存区的指针
闭包:指的是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
二、对象
JS可操纵对象有 JS Engine Object、DOM Element、BOM Element
//js obj
var obj={};
//DOM
var el=document.createElement
//BOM
window
JS Obj和DOM可以增加(Create)、读取(Retrieve)(重新得到数据)、更新(Update)和删除(Delete),因此可能发生内存泄漏。
Window对象是JavaScript层级中的顶层对象,Window对象表示一个浏览器窗口或一个框架(frame),会在body或frameset标签出现时被自动创建。
三、回收机制
ECMAJavaScript要求使用自动垃圾收集机制。但是规范没用规定如何实现,所以不同的浏览器实现方式不一样。一般的思想就是模仿JAVA语言.即如果对象不再“可引用(由于不存在对它的引用。使执行代码无法再访问到它)”时,该对象就成为垃圾收集的目标。因而,在将来的某个时刻会将这个对象销毁并将它所占用的一切资源释放,以便操作系统重新利用。同时。若只有两个相互引用的对象,他们不会被第三者引用的话。这两个对象也会被回收。反言之,如果某对象被其他对象引用,引用者又被引用,只要该引用链不形成循环,那么只要最初的引用调用者的生命周期不结束,那么整条链上的变量的生命周期都不会结束。正常情况下。一个函数的生命周期结束时就会满足垃圾收集条件。此时,作用域中的对象,都不再“可引用”,因此将成为垃圾收集的目标。然而由于不同浏览器的实现不同,在IE浏览器中对垃圾收集出现了一些问题,如果使用闭包不当,在一些特殊情况下,将会引起内存的泄漏。[2]
IE使用JS Obj内存回收机制采用Mark and Sweep算法,很好地释放孤岛内存。[1]
但IE浏览器分别使用了 垃圾收集(JavaScript对象管理)和引用计数(DOM对象管理)的混合系统,如果同时包含JS Obj和DOM对象,IE则无法回收,从而导致严重的内存泄漏。
4种内存泄漏机制
1.循环引用(所有内存泄漏机制的最根本原因)
解决方法:确定变量不再使用了将其设为null
2.闭包(可导致跨页内存泄漏)
闭包的词法作用域(Lexical scope),会延长方法参数和局部变量的生命周期,从而导致循环引用。
结合垃圾收集机制来看,一个闭包就是当一个函数返回时,一个没有释放资源的栈区,更加通俗的讲就是方法内部变量的生命周期超过了方法本身的生命周期。
解决方法:
避免监听方法体内隐式引用参数变量
绑定了方法体后,无用的时要记得解绑清空。
四、其他问题
以下部分针对各个浏览器的问题,提出来讲。
在IE9一下,更改DOM的属性是,如使用jQuery中的$.prop(name,value)后,再删除DOM,新增的属性将无法删除,造成内存泄漏的现象,建议使用$.data(name,value)将其属性保存在jQuery的缓存中。或在删除DOM结构时,将新增的属性使用$.removeProp将其先移除。
参考资料:
[1] JS魔法堂:再识IE的内存泄露