一尘不染

防止AJAX内存泄漏

ajax

我正在设计一个Web应用程序,该应用程序旨在显示一堆使用AJAX定期更新的数据。一般的使用场景是用户将整天保持打开状态,然后不时浏览一下。

我遇到的问题是浏览器的内存占用量随时间缓慢增长。Firefox和IE
7(尽管不是Chrome)都在发生这种情况。几个小时后,它可能导致IE7占用约200MB的内存,而FF3导致占用约400MB的内存。

经过大量测试,我发现只有在响应AJAX调用时才会发生内存泄漏。如果服务器没有任何响应,我可以将页面保持打开状态数小时,并且占用空间不会增加。

我正在为AJAX调用使用原型。因此,我猜测onSuccess回调在创建这些内存泄漏时存在问题。

有没有人对使用原型/ AJAX防止内存泄漏有任何提示?或任何方法如何解决此问题?

编辑:发现问题出在我正在使用的js图形库中。可以在这里看到。


阅读 205

收藏
2020-07-26

共1个答案

一尘不染

您可以注意的最大事件是事件及其分配方式。

例如,采用这种情况(因为您尚未提供):

<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,所以也没有办法为内目标替换它的内容,以孤儿的活动。

2020-07-26