详谈JavaScript内存泄漏

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内存泄漏的相关内容以及解决方案了,有需要的小伙伴可以参考下

(0)

相关推荐

  • 防止动态加载JavaScript引起的内存泄漏问题

    为了释放脚本资源,通常在返回后还要一些进行额外的处理. 复制代码 代码如下: script = document.createElement('script'); script.src = 'http://example.com/cgi-bin/jsonp?q=What+is+the+meaning+of+life%3F'; script.id = 'JSONP'; script.type = 'text/javascript'; script.charset = 'utf-8'; // 标签加

  • 插件:检测javascript的内存泄漏

    转自:http://www.ajaxjs.com/yuicn/bbs/ShowPost.asp?ThreadID=6 2006-10-18 @ 07:59:29 · 作者 volcano Javascript的内存泄漏,不是太可怕.它只会悄悄的,慢慢的把你的浏览器拖的巨慢无比,让你愤怒的拍案而起,大骂微软出品的破烂浏览器危害社会.这一切有可能并不是浏览器的错,可能只是因为网页上有些javascript的内存泄漏罢了. 在科技日益发达今天,我们有必要武装自己,以及自己的浏览器,这样万一浏览器倒下了

  • javascript removeChild 导致的内存泄漏

    为得求证,自己写了一个页面来验证怎样内存泄漏.代码如下 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head

  • JavaScript中内存泄漏的介绍与教程(推荐)

    本文主要给大家详细介绍了关于JavaScript中内存泄漏的相关内容,文中介绍的非常详细,对大家具有一定的参考学习价值,下面来一起看看详细的介绍: 一.什么是内存泄漏? 程序的运行需要内存.只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存. 对于持续运行的服务进程(daemon),必须及时释放不再用到的内存.否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃. 不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak). 有些语言(比如 C 语言)必须手动

  • 深入理解JavaScript程序中内存泄漏

    垃圾回收解放了我们,它让我们可将精力集中在应用程序逻辑(而不是内存管理)上.但是,垃圾收集并不神奇.了解它的工作原理,以及如何使它保留本应在很久以前释放的内存,就可以实现更快更可靠的应用程序.在本文中,学习一种定位 JavaScript 应用程序中内存泄漏的系统方法.几种常见的泄漏模式,以及解决这些泄漏的适当方法. 一.简介 当处理 JavaScript 这样的脚本语言时,很容易忘记每个对象.类.字符串.数字和方法都需要分配和保留内存.语言和运行时的垃圾回收器隐藏了内存分配和释放的具体细节. 许

  • javascript垃圾收集机制与内存泄漏详细解析

    javascript具有自动垃圾收集机制,也就是说,执行环境会负责管理代码执行过程中的使用的内存.而在C和C++之类的语言中,开发人员的一项基本任务就是手动跟踪内存的使用情况,这是造成许多问题的一个根源.在编写javascript程序时候,开发人员不用再关心内存使用的问题,所需内存的分配 以及无用的回收完全实现了自动管理.这种垃圾收集机制的原理其实很简单:找出那些不再继续使用的变量,然后释放其中占用的内存.为此,垃圾收集器会按照固定的时间间隔(或代码执行中预设的收集时间),周期性的执行这一操作.

  • 浅析Node.js中的内存泄漏问题

    这篇文章是由Mozilla的Identity团队带来的 A Node.JS Holiday Season系列文章的首篇,该团队上个月发布了 Persona的第一个测试版本.在开发Persona时我们构建了一系列的工具,包括了从调试,到本地化,到依赖管理以及更多的方面.在这一系列的文章中我们将与社区分享我们的经验和这些工具,这对任何想用node.js建立一个高可用性服务的人都很有用.我们希望您能喜欢这些文章,并期待看到您的想法和贡献. 我们将从一篇关于Node.js的实质性问题:内存泄漏的主题文章

  • 详谈JavaScript内存泄漏

    1.什么是闭包.以及闭包所涉及的作用域链这里就不说了. 2.JavaScript垃圾回收机制 JavaScript不需要手动地释放内存,它使用一种自动垃圾回收机制(garbage collection).当一个对象无用的时候,即程序中无变量引用这个对象时,就会从内存中释放掉这个变量. 复制代码 代码如下: var s = [ 1, 2 ,3];     var s = null;     //这样原始的数组[1 ,2 ,3]就会被释放掉了. 3.循环引用 三个对象 A .B .C AàBàC :

  • JavaScript内存泄漏的处理方式

    下面就是小编整理的关于JS遇到内存泄漏问题时应该采取的处理方式. 随着现在的编程语言功能越来越成熟.复杂,内存管理也容易被大家忽略.本文将会讨论JavaScript中的内存泄漏以及如何处理,方便大家在使用JavaScript编码时,更好的应对内存泄漏带来的问题. 概述 像C语言这样的编程语言,具有简单的内存管理功能函数,例如malloc( )和free( ).开发人员可以使用这些功能函数来显式地分配和释放系统的内存. 当创建对象和字符串等时,JavaScript就会分配内存,并在不再使用时自动释

  • 一篇文章弄懂javascript内存泄漏

    1.什么是内存泄漏 在了解什么是内存泄漏之前, 我们应该要对内存是什么有个概念, 随机存取存储器(英语:Random Access Memory,缩写:RAM)是与 CPU 直接交换数据的内部存储器.它可以随时读写, 而且速度很快,通常作为操作系统或其他正在运行中的程序的临时资料存储介质. 什么是内存泄漏? : 程序不再需要使用的内存, 但是又没有及时释放, 就叫做内存泄漏! 然后在理解泄漏之前, 我们的了解下内存的管理, 在一些底层语言中, 如C语言, 内存是需要开发者自己分配和释放的, 通过

  • 一文搞懂如何避免JavaScript内存泄漏

    目录 一.什么是内存泄漏 二.常见的内存泄漏 1.意外的全局变量 2. 计时器 3. 闭包 4. 事件监听器 5.缓存 6.分离的DOM元素 三.识别内存泄漏 1.使用性能分析器可视化内存消耗 2. 识别分离的 DOM 节点 大家好,我是CUGGZ.SPA(单页应用程序)的兴起,促使我们更加关注与内存相关的 JavaScript 编码实践.如果应用使用的内存越来越多,就会严重影响性能,甚至导致浏览器的崩溃.下面就来看看JavaScript中常见的内存泄漏以及如何避免内存泄漏. 一.什么是内存泄漏

  • 手把手教你如何排查Javascript内存泄漏

    目录 引言 如何判断我的应用发生了内存泄漏 Performance和Memory都可以用来定位内存问题,先用谁呢 通过Memory面板定位内存泄漏的流程通常是怎么样的呢 为什么我的内存快照记录下来之后看不懂,还出现了很多奇怪的变量 快照里有一些“Detached DOM tree”,是什么意思 Shallow size 和 Retained size,它们有什么不同 Memory里的Summary视图, Comparison视图, Dominators视图和Containment视图分别有什么不

  • Meta开源JavaScript内存泄漏监测工具MemLab安装使用

    目录 一.MemLab简介 二.工作原理 三.基本使用 3.1 安装与使用 3.2 堆分析与研究 3.3 Memlab API 3.4 内存断言 一.MemLab简介 上周,Facebook母公司Meta 宣布了开源 MemLab,一个基于 Chromium 的浏览器的 JavaScript 应用程序内存泄漏监测工具.同时,Facebook 技术团队指出:“应用程序的性能和功能正确性问题通常会被用户立即留意到.然而内存泄漏却不一样,它不容易被立即察觉,但它每次都会吃掉一大块内存,使得整个网络会话

  • 详谈C++的内存泄漏问题

    1)有多少new就有多少delete.而且配对的new与delete要尽量在一个函数中.如果子函数中需要返回的数据是通过new来创建的,我的处理方式一般是在需要调用这个函数的位置将对应的数据规模创建好,并且通过指针或是引用传递到子函数中. 2)本人比较粗心大意,又一次在编码的过程中 竟然将delete语句放在了return语句的后面,导致程序运行的过程中会因内存不足二崩溃.检查了不下20遍才检查出来,真是哭的心情都有了.希望大家以我为戒,一定把return语句放在函数的最后面,估计也就我一个人犯

随机推荐