详谈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 相关文章推荐
javascript 异步页面查询实现代码(asp.net)
May 26 Javascript
juqery 学习之六 CSS--css、位置、宽高
Feb 11 Javascript
js实现发送验证码后的倒计时功能
May 28 Javascript
jquery动画效果学习笔记(8种效果)
Nov 13 Javascript
基于Jquery和html5的7款个性化地图插件
Nov 17 Javascript
JS之相等操作符详解
Sep 13 Javascript
jquery easyui DataGrid简单示例
Jan 23 Javascript
js实现模糊匹配功能
Feb 15 Javascript
js获取浏览器和屏幕的各种宽度高度
Feb 22 Javascript
js中怎么判断两个字符串相等的实例
Jan 17 Javascript
AJAX在JQuery中的应用详解
Jan 30 jQuery
vue-router 按需加载 component: () => import() 报错的解决
Sep 22 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 session和cookie使用说明
2010/04/07 PHP
深入php数据采集的详解
2013/06/02 PHP
修改Laravel5.3中的路由文件与路径
2016/08/10 PHP
PHP中in_array函数使用的问题与解决办法
2016/09/11 PHP
javascript void(0)的妙用
2009/10/21 Javascript
Js 回车换行处理的办法及replace方法应用
2013/01/24 Javascript
动态加载dtree.js树treeview(示例代码)
2013/12/17 Javascript
jquery $.trim()方法使用介绍
2014/05/21 Javascript
使用jquery实现的一个图片延迟加载插件(含图片延迟加载原理)
2014/06/05 Javascript
js操作滚动条事件实例
2015/01/29 Javascript
简述JavaScript中正则表达式的使用方法
2015/06/15 Javascript
jquery带翻页动画的电子杂志代码分享
2015/08/21 Javascript
js实现鼠标点击左上角滑动菜单效果代码
2015/09/06 Javascript
基于JavaScript实现轮播图原理及示例
2020/04/10 Javascript
使用jQuery 操作table 完成单元格合并的实例
2017/12/27 jQuery
详解react阻止无效重渲染的多种方式
2018/12/11 Javascript
jQuery Datatables 动态列+跨列合并实现代码
2020/01/30 jQuery
javascript实现留言板功能
2020/02/08 Javascript
[05:46]DOTA2英雄梦之声_第18期_陈
2014/06/20 DOTA
python使用正则搜索字符串或文件中的浮点数代码实例
2014/07/11 Python
python买卖股票的最佳时机(基于贪心/蛮力算法)
2019/07/05 Python
python读取ini配置的类封装代码实例
2020/01/08 Python
浅谈Pytorch torch.optim优化器个性化的使用
2020/02/20 Python
英国女性运动服品牌:Sweaty Betty
2018/11/08 全球购物
澳大利亚在线购买葡萄酒:The Wine Collective
2020/02/20 全球购物
大学生实习证明范本
2014/01/15 职场文书
运动会邀请函范文
2014/01/31 职场文书
教师党性分析材料
2014/02/04 职场文书
军人违纪检讨书
2014/02/04 职场文书
元旦晚会策划方案
2014/02/18 职场文书
工程项目建议书范文
2014/03/12 职场文书
网页美工求职信范文
2014/04/17 职场文书
2014年项目经理工作总结
2014/11/24 职场文书
先进班组材料范文
2014/12/25 职场文书
全国法制宣传日活动总结
2015/05/05 职场文书
Python实现排序方法常见的四种
2021/07/15 Python