我正在开发一个Web应用程序,它旨在显示一组使用AJAX定期更新的数据。一般使用场景是用户将其全天保持打开状态,并偶尔看一眼。
我遇到的问题是浏览器的内存占用时间越来越慢。这种情况在Firefox和IE 7中都有发生(尽管不在Chrome中)。几个小时后,它可以使IE7的占用空间大约为200MB,FF3的占用空间大约为400MB。
经过大量测试后,我发现只有在响应AJAX调用时才会发生内存泄漏。如果服务器没有响应任何内容,我可以将页面打开几个小时,而且足迹不会增长。
我正在使用原型进行AJAX调用。所以,我猜测onSuccess回调存在一个问题,造成这些内存泄漏。
有没有人有关于使用原型/ AJAX防止内存泄漏的任何提示?或者有关如何解决此问题的任何方法?
编辑:发现问题出在我正在使用的js图形库中。可以看到here。答案 0 :(得分:10)
您可以注意的最重要的事情是事件,以及如何分配它们。
例如,采取这种情况(因为你没有提供):
<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使得确定事件目标的元素变得简单。没有事件被分配给 #ajaxResponseTarget
中的元素,因此无法将其内容替换为来自目标内的孤立事件。
答案 1 :(得分:-3)
我可能错了,但听起来你正在围绕响应对象创建闭包。每个响应对象都是不同的,这会导致内存占用增加。