jQuery内存泄漏模式和原因 [英] jQuery memory leak patterns and causes

查看:140
本文介绍了jQuery内存泄漏模式和原因的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

jQuery中的一些标准问题或编码模式会导致内存泄漏?




我在StackOverflow上看到了一些与ajax()调用或jsonp或DOM删除有关的问题。大多数jQuery内存泄漏问题都集中在特定问题或浏览器上,并且在jQuery中列出标准内存泄漏模式会很好。

以下是关于SO的一些相关问题:



网上资源:


解决方案

JavaScript是通过引用计数完成的 - 虽然对象的引用仍然存在,但不会被释放。这意味着在单个页面应用程序中创建内存泄漏是微不足道的,并且可能导致来自java背景的那些内存泄漏。这不是特定于JQuery的。例如,以下面的代码为例:

  function MyObject = function(){
var _this = this;
this.count = 0;
this.getAndIncrement = function(){
_this.count ++;
return _this.count;



(var i = 0; i <10000; i ++){
var obj = new MyObject();
obj.getAndIncrement();
}

在查看内存使用情况之前,这看起来很正常。由于_this指针,MyObject的实例从不释放,而页面处于活动状态(增加i的最大值以更显着地看到它)。 (在旧版本的IE中,它们从未被释放,直到程序退出。)由于JavaScript对象可能在帧之间共享(我不建议尝试这种方式,因为它是严重的气质)。有时甚至在现代浏览器中使用javascript对象可能比他们想要的要长很多。



在jquery的上下文中,引用通常被存储以节省dom搜索的开销 - 例如: / p>

  function run(){
var domObjects = $(。myClass);
domObjects.click(function(){
domObjects.addClass(。myOtherClass);
});
}

这段代码将永远保留domObject(及其所有内容),因为如果jquery的作者在内部错过了像这样的实例,那么库本身将会泄漏,但更多的时候是客户端代码。



第二个示例可以通过在不再需要指针时明确清除指针来修复:

  function run(){
var domObjects = $(。myClass);
domObjects.click(function(){
if(domObjects){
domObjects.addClass(。myOtherClass);
domObjects = null;
}
});
}

或者再次进行查找:

  function run(){
$(。myClass)。click(function(){
$(。myClass)。addClass (.myOtherClass);
});
}

一个好的经验法则是在定义回调函数的地方小心谨慎,并在可能的情况下避免过多的嵌套。编辑:正如在Erik的评论中指出的那样,你也可以使用这个指针来避免不必要的dom查找: / p>

  function run(){
$(。myClass)。click(function(){
$(this).addClass(。myOtherClass);
});
}


What are some of the standard issues or coding patterns in jQuery which lead to memory leaks?


I have seen a number of questions related to the ajax() call or jsonp or DOM removal on StackOverflow. Most of the jQuery memory leak questions are focussed on specific issues or browsers and it would be nice to have a listing of the standard memory leak patterns in jQuery.

Here are some related questions on SO:

Resources on the web:

解决方案

From what I understand, memory management in javascript is accomplished by reference counting - while a reference to an object still exists, it will not be deallocated. This means that creating a memory leak in a single page application is trivial, and can trip up those of use coming from a java background. This is not specific to JQuery. Take the following code for example:

function MyObject = function(){
   var _this = this;
   this.count = 0;
   this.getAndIncrement = function(){
       _this.count++;
       return _this.count;
   }
}

for(var i = 0; i < 10000; i++){
    var obj = new MyObject();
    obj.getAndIncrement();
}

It will look normal until you look at memory usage. Instances of MyObject are never deallocated while the page is active, due to the "_this" pointer (increase the max value of i to see it more dramatically.). (In older versions of IE they were never deallocated until the program exits.) Since javascript objects may be shared between frames (I don't recommend trying this as it is seriously temperamental.), there are cases where even in a modern browser javascript objects can hang around a lot longer than they are meant to.

In the context of jquery, references are often stored to save the overhead of dom searching - for example:

function run(){
    var domObjects = $(".myClass");
    domObjects.click(function(){
        domObjects.addClass(".myOtherClass");
    });
}

This code will hold on to domObject (and all its contents) forever, because of the reference to it in the callback function.

If the writers of jquery have missed instances like this internally, then the library itself will leak, but more often it is the client code.

The second example can be fixed by explicitly clearing the pointer when it is no longer required:

function run(){
    var domObjects = $(".myClass");
    domObjects.click(function(){
        if(domObjects){
            domObjects.addClass(".myOtherClass");
            domObjects = null;
        }
    });
}

or doing the lookup again:

function run(){
    $(".myClass").click(function(){
        $(".myClass").addClass(".myOtherClass");
    });
}

A good rule of thumb is to be careful where you define your callback functions, and avoid too much nesting where possible.

Edit: As was pointed out in the comments by Erik, you could also use the this pointer to avoid the unnescessary dom lookup:

function run(){
    $(".myClass").click(function(){
        $(this).addClass(".myOtherClass");
    });
}

这篇关于jQuery内存泄漏模式和原因的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆