【问题标题】:Why does IE leak memory when wrapping an HTML response in a jQuery object?为什么在 jQuery 对象中包装 HTML 响应时 IE 会泄漏内存?
【发布时间】:2013-03-14 18:03:12
【问题描述】:

我试图弄清楚为什么 IE 在将 AJAX 请求的 HTML 页面包装到 jQuery 对象中进行处理时会泄漏内存。用户可能会访问页面并让它停留几分钟或几小时,因此页面使用 jQuery 的 ajax 方法每分钟几次获取新数据,然后我将页面的重要部分替换为新的预渲染数据。

此时,我已将其范围缩小为一次调用 - 当调用 $(data) 来包装 HTML 字符串时,内存会出现一点峰值,并且似乎从未被垃圾回收。随着时间的推移,使用了数百 MB,我不得不重新加载页面或重新启动 IE。

This fiddle 能够重现该问题。它使用 AJAX 请求页面,然后在紧密循环中调用$(data) 以夸大泄漏。 Chrome 和 Firefox 似乎都像我预期的那样做出反应(内存被回收),但 IE 表现不佳。惊喜。

使用 Process Explorer,我发现在运行上述小提琴两次后内存消耗急剧增加。

我目前在标准模式下使用 IE9。

为什么会这样?有解决办法吗?

更新

这是一个fiddle,它在不使用 AJAX 的情况下演示了该问题。

【问题讨论】:

  • 我看到内存增加了,但很快就被释放了。即使增加到 10000 次迭代也有相同的结果。
  • @KevinB 我相信您在 IE10 标准下对其进行了测试,因为我做了同样的事情并看到了资源被释放,但是正如 Pwninstein 在 IE9 上提到的完全不同的故事,我做了一次并看到了我的资源从 50MB 到 350MB 并留在那里......
  • 我这台机器上没有 IE10。 Windows 7 IE9
  • @KevinB 什么浏览器/操作系统?我可以用 Win7 (x64) + IE9.0.8112 (x86) 的小提琴来重现它
  • 我确实看到了泄漏。让我们缩小一点。如果你简单地使用
    foobar
    ,就没有泄漏。我们需要缩小范围,找出导致它的确切原因,排除 ajax 请求。

标签: jquery ajax internet-explorer memory-leaks


【解决方案1】:

我找到了解决上述问题的方法。

在解决此问题时,我尝试了各种方法来防止发生泄漏。我想出的解决方案是放弃使用$.ajax 来检索数据并使用$() 来包装结果。相反,我使用$('#destination').load('sourceUrl #selector')(参见documentation)将数据推入隐藏的div,然后以这种方式处理结果。

原来$.load 在幕后使用$.parseHTML 来操纵结果并将它们推到指定位置(而$() 显然没有)。 See here 源代码行。

  • $(htmlText) 泄漏
  • $(bodyText) 不泄露
  • $.parseHtml(htmlText)慢慢泄漏(?)
  • $.parseHtml(bodyText) 不会泄露

这里有一个fiddle 来演示。

我不知道为什么它的行为方式是这样的,但它的短处似乎是:尽可能避免解析完整的 HTML 文档。

【讨论】:

    【解决方案2】:

    我看到了你所看到的,当我更改代码以在每次调用成功时重新分配函数时,神奇地它没有泄漏(至少在我的环境中。)

    所以,我的解决方案很愚蠢,但它似乎对我有用。对你有用吗?

    $(function(){
        $.ajaxSetup({ cache: false });
    
        $('#go').click(performCall);
    });
    
    function performCall() {
        $('#timestamp').text('Working...');
    
        $.ajax({
           url: 'http://fiddle.jshell.net/',
            success: function(){
                var func = function(data, textStatus, jqXHR) {
                    $('#timestamp').text('Done at ' + new Date());
                    for(var x = 0; x < 100; x++) {
                        var $a = $(data);
                    }
                };
                func();
            }
       });
    }
    

    http://jsfiddle.net/tCvUw/

    【讨论】:

    • 谢谢,MrLeap。我试过了,我看到了你描述的内容(没有泄漏),但看起来data 以未定义的形式返回,所以$(data) 没有做任何事情。将数据、textStatus 和 jqXHR 移动到匿名的“成功”函数定义中使其工作,但它仍然像以前一样泄漏。
    • 是的,我现在也看到了。德普。我会继续关注的。
    • 没问题 - 我很欣赏这个问题的新视角 :) 请参阅我对非 AJAX 小提琴的更新答案。
    猜你喜欢
    • 1970-01-01
    • 2011-06-17
    • 2011-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多