Javascript 浏览器通过AJAX+;设定间隔

Javascript 浏览器通过AJAX+;设定间隔,javascript,jquery,ajax,memory-leaks,Javascript,Jquery,Ajax,Memory Leaks,我需要在给定的时间间隔内用JavaScript更新大量数据。问题是,无论我使用什么JS库(甚至是裸骨JS),所有浏览器似乎都会在每个AJAX请求上分配内存,并且之后无法释放内存。这是一个剪下的样本,应该会重现错误: <!DOCTYPE html> <html lang="en"> <head> <title>Memleak Test</title> <

我需要在给定的时间间隔内用JavaScript更新大量数据。问题是,无论我使用什么JS库(甚至是裸骨JS),所有浏览器似乎都会在每个AJAX请求上分配内存,并且之后无法释放内存。这是一个剪下的样本,应该会重现错误:

    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>Memleak Test</title>
            <meta charset="utf-8" />
            <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"></script>
            <script type="text/javascript">

                function readData() {
                    $.getJSON('data.php');
                }

                $(document).ready(function() {
                    setInterval(readData, 1000);
                });
            </script>
        </head>
        <body>
            <div id="content"></div>
        </body>
    </html>

膜泄漏试验
函数readData(){
$.getJSON('data.php');
}
$(文档).ready(函数(){
设置间隔(读取数据,1000);
});
类似的测试页面可在

以下是有关此的更多信息:

  • 我还尝试将readData()函数作为闭包直接放在setInterval()调用中。这似乎没有什么区别
  • 我在这里使用jQuery,但任何其他库都会产生相同的错误
  • 我的data.php脚本只是用php中的JSON_encode()生成了一个伪JSON对象
  • 我知道这里一秒钟是很短的时间段,在我的制作脚本中,时间段是30秒。我只是想更快地看到效果(在生产应用程序中需要几个小时,但是内存也满了)
  • 这里的问题是,该应用程序将全天候开放

这看起来很简单,我认为我在这里做了一些非常错误的事情,如果这里的一些JS大师能够帮助我,那就太好了

您每秒钟都会轮询服务器。它肯定会消耗掉所有的内存。但是,您可以做的是设置预定义的间隔。然后在轮询之后,如果数据可用,则获取该数据并保持间隔不变,但如果轮询之后还没有可用数据,则增加间隔以确保下一次轮询延迟。这样你可以减少工作量。

看看这篇文章-可能会有帮助吗


(建议使用明显试图避免内存泄漏的特定JQuery方法:并使用“delete”命令尝试释放空间)。

由于每次请求都会加载更多数据,因此会增加内存使用量

Clicky:

根据:


您是否尝试过重用调用中的变量?也就是说,不要在处理响应的地方创建新的变量,而是使用相同的变量。说

window.myvar = response["myvar"];

这确实是一个漏洞,这可能有助于垃圾收集器。不过,如果能看到您所做工作的实际代码,那就太好了

同一posted的一个可能问题是如果XHR请求的时间长于轮询周期(平均),则等待处理的请求队列将增加。如果web服务器本身开始积压请求,这可能会变成一个恶性循环

为了避免这种情况,请使用CPS样式的编码,其中下一个操作是使用适当的回调完成的。也就是说,在需要之前不要启动下一个请求(前一个请求完成:成功或失败)——如果需要大量未完成的请求,这种方法仍然可以用于创建具有可控大小的手动请求队列

另外,确保未使用的对象符合回收条件,因为这是GC语言中“内存泄漏”的“标准”原因

快乐编码


文章中的代码不包含任何会固有地泄漏内存的内容。这可能是jQuery内部的问题,但这只是猜测。此外,像Firebug这样监视XHR/web请求的工具可能会消耗大量内存,因此需要检查并确保行为不是海森堡行为



另外,请记住,内存使用率的增加并不意味着内存泄漏,除非它变得无限大。垃圾收集周期只有在主机喜欢时才会发生。

只是想一想,您应该使用setTimeout而不是setInterval,然后在超时时再次设置超时

这样,如果由于某种原因无法跟踪设置间隔,您就不会面临设置间隔失控的风险:

我还认为jqueryajax有一个成功回调,您可以使用它作为设置超时的点。这样,正如本文其他部分提到的那样,您不会以请求重叠而告终


(刚刚检查,有一个成功的回调)

你好,艾哈迈德,谢谢你的反馈。我在我的第一篇帖子中说,在制作过程中,这被设置为30秒,而只是设置为1秒,以便P问题更快地显现出来。另外,我无法添加延迟,因为2小时后,新数据的可能性与现在相同。无论如何谢谢你@moidaschl好的,除了清理内存(垃圾收集)之外,您必须在每个数据加载上放置指示器,并且不应该加载所有内容,而应该仅从该指示器加载。我希望你能理解我的意思。嗯,不是真的,如果你能多解释一下指标的内容就好了(或者你有关于这个主题的链接吗?)可以使用最新的行ID设置变量,如果行ID大于当前行ID,则下一次ajax获取应该继续。如果我理解正确,这将导致更多但更小的ajax查询,对吗?我在这里面临的问题是,我有n个条目要加载,但在下一次获取时也可能有n+1或n-1个条目,因此我需要在每个请求周期中提取整个数据集。感谢链接。事实上,这在所有浏览器中都会发生,不仅仅是IE。起初我以为我的数据操作会导致内存增加,但后来我只是运行AJAX查询(如上面的示例所示),不做任何其他操作,它仍然会增加。我还尝试了html()和删除内容,但在这种情况下没有帮助。无论如何谢谢你!注意,使用delete是个坏主意,如果你在2013年或之后阅读这个答案,你不觉得吗
window.myvar = response["myvar"];