详谈JavaScript内存泄漏


Posted in Javascript onNovember 14, 2014

1、什么是闭包、以及闭包所涉及的作用域链这里就不说了。

2、JavaScript垃圾回收机制

     JavaScript不需要手动地释放内存,它使用一种自动垃圾回收机制(garbage collection)。当一个对象无用的时候,即程序中无变量引用这个对象时,就会从内存中释放掉这个变量。

    var s = [ 1, 2 ,3];

    var s = null;

    //这样原始的数组[1 ,2 ,3]就会被释放掉了。

3、循环引用

     三个对象 A 、B 、C

     AàBàC :A的某一属性引用着B,同样C也被B的属性引用着。如果将A清除,那么B、C也被释放。

     AàBàCàB :这里增加了C的某一属性引用B对象,如果这是清除A,那么B、C不会被释放,因为B和C之间产生了循环引用。

    var a = {};

    a.pro = { a:100 };

    a.pro.pro = { b:100 };

    a = null ; 

    //这种情况下,{a:100}和{b:100}就同时也被释放了。

            

    var obj = {};

    obj.pro = { a : 100 };

    obj.pro.pro = { b : 200 };

    var two = obj.pro.pro;

    obj = null;    

    //这种情况下 {b:200}不会被释放掉,而{a:100}被释放了。

 

4、循环引用和闭包

    function outer(){

        var obj = {};

        function inner(){ 

            //这里引用了obj对象

        }

        obj.inner = inner;

    }

这是一种及其隐蔽的循环引用,。当调用一次outer时,就会在其内部创建obj和inner两个对象,obj的inner属性引用了inner;同样inner也引用了obj,这是因为obj仍然在innerFun的封闭环境中,准确的讲这是由于JavaScript特有的“作用域链”。
因此,闭包非常容易创建循环引用,幸运的是JavaScript能够很好的处理这种循环引用。

5、IE中的内存泄漏

    IE中的内存泄漏有好几种,这里有详细的解释(http://msdn.microsoft.com/en-us/library/bb250448.aspx)。

    这里只讨论其中一种,即循环引用所造成的内存泄漏,因为,这是一种最普遍的情况。

    当在DOM元素或一个ActiveX对象与普通JavaScript对象之间存在循环引用时,IE在释放这类变量时存在特殊的困难,最好手动切断循环引用,这个bug在IE 7中已经被修复了(http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html)。

   “IE 6 suffered from memory leaks when a circular reference between several objects, among which at least one DOM node, was created. This problem has been solved in IE 7. ”

    如果上面的例子(第4点)中obj引用的不是一个JavaScript Function对象(inner),而是一个ActiveX对象或Dom元素,这样在IE中所形成的循环引用无法得到释放。

    function init(){

        var elem = document.getElementByid( 'id' );

        elem.onclick = function(){

            alert('rain-man');

            //这里引用了elem元素

        };

    }

Elem引用了它的click事件的监听函数,同样该函数通过其作用域链也引用回了elem元素。这样在IE中即使离开当前页面也不会释放这些循环引用。

6、解决方法

   基本的方法就是手动清除这种循环引用,下面一个十分简单的例子,实际应用时可以自己构建一个addEvent()函数,并且在window的unload事件上对所有事件绑定进行清除。

    function outer(){

        var one = document.getElementById( 'one' );

        one.onclick = function(){};

    }

    window.onunload = function(){

        var one = document.getElementById( 'one' );

        one.onclick = null;

    };

 其它方法(by:Douglas Crockford)

/**

 * 遍历某一元素节点及其所有后代元素

 *

 * @param Elem node  所要清除的元素节点

 * @param function func  进行处理的函数

 * 

 */

function walkTheDOM(node, func) {

    func(node); 

    node = node.firstChild; 

    while (node) { 

        walkTheDOM(node, func); 

        node = node.nextSibling; 

    } 

} 

/**

 * 清除dom节点的所有引用,防止内存泄露

 *

 * @param Elem node  所要清除的元素节点

 * 

 */

function purgeEventHandlers(node) {

    walkTheDOM(node, function (e) {

        for (var n in e) {            

            if (typeof e[n] === 

                    'function') {

                e[n] = null;

            }

        }

    });

以上就是JavaScript内存泄漏的相关内容以及解决方案了,有需要的小伙伴可以参考下

Javascript 相关文章推荐
屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 的javascript代码
Apr 01 Javascript
Jquery 插件开发笔记整理
Jan 17 Javascript
修改jQuery Validation里默认的验证方法
Feb 14 Javascript
jQuery学习笔记之控制页面实现代码
Feb 27 Javascript
排序算法的javascript实现与讲解(99js手记)
Sep 28 Javascript
angular简介和其特点介绍
Jan 29 Javascript
jquery实现鼠标悬浮停止轮播特效
Aug 20 Javascript
jQuery代码实现实时获取时间
Jan 29 Javascript
Flutter部件内部状态管理小结之实现Vue的v-model功能
Jun 11 Javascript
JS实现音乐导航特效
Jan 06 Javascript
JS实现烟花爆炸效果
Mar 10 Javascript
Vue前端判断数据对象是否为空的实例
Sep 02 Javascript
js与C#进行时间戳转换
Nov 14 #Javascript
jquery ui bootstrap 实现自定义风格
Nov 14 #Javascript
使用node.js 制作网站前台后台
Nov 13 #Javascript
JavaScript 作用域链解析
Nov 13 #Javascript
jQuery $命名冲突解决方案汇总
Nov 13 #Javascript
js获取字符串最后一位方法汇总
Nov 13 #Javascript
实现js保留小数点后N位的代码
Nov 13 #Javascript
You might like
PHP教程之PHP中shell脚本的使用方法分享
2012/02/23 PHP
PPK 谈 JavaScript 的 this 关键字 [翻译]
2009/09/29 Javascript
{}与function(){}选用空对象{}来存放keyValue
2012/05/23 Javascript
jquery.ajax的url中传递中文乱码问题的解决方法
2014/02/07 Javascript
JS实现的简单鼠标跟随DiV层效果完整实例
2015/10/31 Javascript
jquery中ajax跨域方法实例分析
2015/12/18 Javascript
Javascript 事件冒泡机制详细介绍
2016/10/10 Javascript
vue.js实例todoList项目
2017/07/07 Javascript
three.js中3D视野的缩放实现代码
2017/11/16 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
2019/02/15 jQuery
JavaScript使用表单元素验证表单的示例代码
2019/08/20 Javascript
微信小程序点击保存图片到本机功能
2019/12/13 Javascript
Vue中import from的来源及省略后缀与加载文件夹问题
2020/02/09 Javascript
vue实现购物车结算功能
2020/06/18 Javascript
在Python的Django框架中simple-todo工具的简单使用
2015/05/30 Python
python实现文件快照加密保护的方法
2015/06/30 Python
Python实现字符串匹配算法代码示例
2017/12/05 Python
Python实现判断给定列表是否有重复元素的方法
2018/04/11 Python
python之django母板页面的使用
2018/07/03 Python
python TKinter获取文本框内容的方法
2018/10/11 Python
python利用pandas将excel文件转换为txt文件的方法
2018/10/23 Python
call在Python中改进数列的实例讲解
2020/12/09 Python
用CSS3写的模仿iPhone中的返回按钮
2015/04/04 HTML / CSS
西班牙在线宠物商店:zooplus.es
2017/02/24 全球购物
应届毕业生应聘自荐信
2013/12/07 职场文书
经济管理专业自荐信
2013/12/30 职场文书
银行学习十八大感想
2014/01/11 职场文书
自强之星事迹材料
2014/05/12 职场文书
女生抽烟检讨书
2014/10/05 职场文书
寒假社会实践个人总结
2015/03/06 职场文书
建国大业观后感
2015/06/01 职场文书
幼儿园庆六一主持词
2015/06/30 职场文书
聘任书格式及范文
2015/09/21 职场文书
加强党性修养心得体会
2016/01/21 职场文书
windows安装python超详细图文教程
2021/05/21 Python
Java8中接口的新特性使用指南
2021/11/01 Java/Android