JavaScript内存泄漏

2016-02-19 16:17 6 1 收藏

下面是个超简单的JavaScript内存泄漏教程,图老师小编精心挑选推荐,大家行行好,多给几个赞吧,小编吐血跪求~

【 tulaoshi.com - Web开发 】

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

  2、JavaScript垃圾回收机制 

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

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

    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中的内存泄漏

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/webkaifa/)

   IE中的内存泄漏有好几种,这里有详细的解释(http://msdn.microsoft.com/en-us/library/bb250448.aspx),园子里也有翻译了(http://www.cnblogs.com/birdshome/archive/2006/05/28/ie_memoryleak.html)。

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

   当在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;
    };

来源:http://www.tulaoshi.com/n/20160219/1611546.html

延伸阅读
标签: Web开发
作者: Abhijeet Bhattacharya (abhbhatt@in.ibm.com), 系统软件工程师, IBM India Kiran Shivarama Shivarama Sundar (kisundar@in.ibm.com), 系统软件工程师, IBM India 2007 年 5 月 28 日 如果您知道内存泄漏的起因,那么在 JavaScript 中进行相应的防范就应该相当容易。在这篇文章中,作者 Kiran Sundar 和 Abhijeet Bhattacharya 将带...
尽管这个概念已经让人说滥了 ,还是想简单记录一下, 以备以后查询。 代码如下: #ifdef _DEBUG #define DEBUG_CLIENTBLOCK   new( _CLIENT_BLOCK, __FILE__, __LINE__) #else #define DEBUG_CLIENTBLOCK #endif #define _CRTDBG_MAP_ALLOC #include crtdbg.h #ifdef _DEBUG #define new DEBUG_CLIENTBLOCK #endif int _tmain(int ...
具有动态的分配和释放内存的能力是C/C++程序语言的重要特色之一。VisualC++ debugger和CRT库提供了一系列有效的检测和鉴定内存泄漏的工具。 设置内存泄漏检测 检测内存泄漏的基本工具是调试器和CRT调试堆函数。为了使用调试堆函数,在你的程序中你必须含有下面的说明: #define _CRTDBG_MAP_ALLOC #includestdlib.h #includecrtdbg.h 必...
标签: 电脑入门
内存超频实际的意义并不会很大,提升效果不会太高,主要还是看平台的整体性能,而且内存超频对内存是有损害的。关于内存超频分两种,一种是在主板BIOS 支持的情况调节内存的主频和电压来达到超频的效果,另外一种就是主板和内存本身不能支持高频率,需要通过修改内存的SPD信息,强行另低频工作在高频来实现。不建议此方法,此方法仅适用于研究...
假如你正在开发一个具有多媒体功能的通讯录程序。这个通讯录除了能存储通常的文字信息如姓名、地址、电话号码外,还能存储照片和声音(可以给出他们名字的正确发音)。 为了实现这个通信录,你可以这样设计: class Image { // 用于图像数据 public: Image(const string& imageDataFileName); ... };...

经验教程

790

收藏

41
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部