【问题标题】:Preventing AJAX memory leaks防止 AJAX 内存泄漏
【发布时间】:2010-09-21 12:34:12
【问题描述】:

我正在开发一个 Web 应用程序,该应用程序旨在显示一组使用 AJAX 定期更新的数据。一般的使用场景是用户将它打开一整天,不时看一眼。

我遇到了一个问题,即浏览器内存占用量随着时间的推移而缓慢增长。这发生在 Firefox 和 IE 7 中(虽然不在 Chrome 中)。几个小时后,它会导致 IE7 的占用空间约为 200MB,而 FF3 的占用空间约为 400MB。

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

我正在为我的 AJAX 调用使用原型。所以,我猜想创建这些内存泄漏的 onSuccess 回调存在问题。

有没有人有任何关于使用原型/AJAX 防止内存泄漏的提示?或者有什么方法可以解决这个问题?

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

【问题讨论】:

    标签: javascript ajax browser memory-leaks


    【解决方案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 上的“点击”也会在 #ajaxResponseTarget 上触发,而 Prototype 可以非常简单地确定哪个元素是事件的目标。没有事件分配给 within #ajaxResponseTarget 的元素,因此无法将其内容替换为来自内部目标的孤立事件。

    【讨论】:

    • +1 好消息,尽管在初始页面加载后我从未创建任何新事件。仍在试图弄清楚我在做什么会导致问题。
    • 如果您不创建任何事件...为什么您接受这个作为您的答案?
    【解决方案2】:

    我可能错了,但听起来您正在围绕响应对象创建闭包。每个响应对象都会有所不同,这会导致内存占用增加。

    【讨论】:

    • 你能解释一下吗?抱歉,我不确定“响应对象周围的关闭”是什么意思。你是说函数吗?
    猜你喜欢
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 2010-12-20
    • 2011-12-05
    相关资源
    最近更新 更多