防止 AJAX 内存泄漏

8
我正在开发一个Web应用程序,旨在显示一堆通过AJAX定期更新的数据。通常使用情况是用户会整天保持打开状态,不时地看一眼。
我遇到了一个问题,浏览器的内存占用量会随着时间缓慢增长。这种情况发生在Firefox和IE 7中(但在Chrome中没有)。几个小时后,可能会导致IE7的内存占用量达到约200MB,FF3的内存占用量达到约400MB。
经过大量测试,我发现只有在AJAX调用得到响应时才会出现内存泄漏。如果服务器没有响应任何内容,我可以让页面打开数小时,而内存占用量不会增加。
我在我的AJAX调用中使用了prototype。因此,我猜想onSuccess回调引起了这些内存泄漏。
有人有关于如何避免prototype / AJAX内存泄漏的提示吗?或者任何解决此问题的方法?
编辑:我发现问题出在我使用的js图形库上。可在这里看到。
2个回答

11

你需要特别注意的是事件以及如何分配它们。

例如,考虑以下情况(因为您没有提供任何一个):

<div id="ajaxResponseTarget">
    ...
</div>
<script type="text/javascript">
    $(someButton).observe('click', function() {
        new Ajax.Updater($('ajaxResponseTarget'), someUrl, {
            onSuccess: function() {
                $$('#ajaxResponseTarget .someButtonClass').invoke('observe', 'click', function() {
                    ...
                });
            }
        });
    });
</script>

这样会导致内存泄漏,因为当更新#ajaxResponseTarget(在内部,Prototype将使用innerHTML)时,具有click事件的元素将从文档中删除,而它们的事件不会被删除。第二次单击someButton时,您将拥有两倍的事件处理程序,垃圾回收无法删除第一组处理程序。

避免这种情况的方法是使用事件委托:

<div id="ajaxResponseTarget">
    ...
</div>
<script type="text/javascript">
    $('ajaxResponseTarget').observe('click', function(e) {
        if(e.element().match('.someButtonClass')) {
            ...
        }
    });
    $(someButton).observe('click', function() {
        new Ajax.Updater($('ajaxResponseTarget'), someUrl);
    });
</script>
由于DOM事件的工作方式,.someButtonClass 上的“click”事件也会触发 #ajaxResponseTarget 上的事件,而Prototype使确定事件目标元素变得非常简单。没有将事件分配给#ajaxResponseTarget内部的元素,在替换其内容时不会使其内部的目标事件失效。

+1 很好的信息,尽管在初始页面加载后我从未创建过任何新事件。仍在努力弄清楚是什么导致了这个问题。 - TM.
1
如果您没有创建任何事件...为什么要将此作为您的答案接受? - Sean

-2
我可能错了,但你似乎在响应对象周围创建闭包。每个响应对象都不同,这会导致内存占用增加。

你能解释一下吗?抱歉,我不确定你所说的“在响应对象周围闭合”是什么意思。你是指一个函数吗? - TM.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接