我有一个网页,使用jquery接收一些产品信息,因为人们正在查看事物,然后显示最后看到的产品图片。这是一个jquery AJAX回调,看起来非常像这样:
if(number_of_things_seen > 10) {
$('#shots li:last-child').remove();
}
$('<li><img src="' + p.ProductImageSmall + '"></li>').prependTo('#shots');
但是,它似乎泄漏了相当多的内存。在视觉上,它做的是正确的,但足迹无限增长。
Safari的DOM检查器显示DOM是我期望的那样,但它似乎保持对它所显示的每个图像的引用(如this screenshot中所见,以防有人感兴趣)。
我添加了
$('#shots li:last-child img').remove();
删除声明没有明显效果。
是否有必要让浏览器发布一些这样的东西?
答案 0 :(得分:2)
浏览器因内存泄漏而臭名昭着。听起来好像页面长时间运行时会出现问题。如何在内存不足之前刷新页面?
window.setTimeout("location.reload()",1000*60*60);//refresh in an hour
答案 1 :(得分:1)
你能尝试改变最后一个孩子的src,看看是否有所作为? 然后,您可以将该元素移动为第一个子元素
//not tested
var $list=$('#shots>li');
$list.filter(':last-child').children('img')
.attr('src', p.ProductImageSmall)
.parent()
.insertBefore( $list.eq(0) );
答案 2 :(得分:1)
来自Mozilla Developer Center on removeChild()
:
删除的子节点仍然存在于内存中,但不再是DOM的一部分。您可以通过oldChild对象引用在代码中稍后重用已删除的节点。
这是关键 - 重用已删除的孩子,而不是重复制作新孩子。
// I'm sure there is a nicer way to do it in jQuery
if(number_of_things_seen > 10) {
var shots = document.getElementById("shots");
var li = shots.getElementsByTagName("LI");
var move = shots.removeChild(li[li.length-1]);
move.getElementsByTagName("IMG")[0].src = p.ProductImageSmall;
shots.insertBefore(move, li[0]);
}
答案 3 :(得分:1)
足迹真的有问题吗?
我怀疑只要您停留在同一个网站上,Safari就会缓存所有图像,而您无能为力。如果幸运的话,Safari会在达到某些限制后释放不需要的对象。
这种行为的原因是,Safari认为这些图像可能是第二次使用,因此它会缓存它们。
答案 4 :(得分:0)
你有多久观察到这种“无限增长”?垃圾收集器的某些实现不一定能够如此快地将内存返回给操作系统。你可以将你想要做的事情提炼成一个真正的简单测试(例如,反复设置图像的src)没有ajax或回调吗?你/你可以尝试使用其他浏览器吗?
答案 5 :(得分:0)
好的我为此构建了一个测试工具,它随机抓取一个新图像并使用我的替换src代码
答案 6 :(得分:0)
达斯汀, 似乎我的代码中的insertBefore语句导致了一些问题。如果你看到这个更进一步的测试用例,即使我正在清空最后一个子节点并插入一个新的dom片段,内存使用仍保持静态。比上次尝试表现更好。
答案 7 :(得分:0)
正如我最近发现的,Firefox中存在一个导致孤立的IMG标记泄露的错误。
这可以通过将图像移动到CSS来解决:
if(number_of_things_seen > 10) {
$('#shots li:last-child').remove();
}
$('<li><div style="background-image: url(\'' + p.ProductImageSmall +
'\'); background-repeat: no-repeat; background-position: center; '+
' width: 20px; height: 20px"></div></li>').prependTo('#shots');
检查这是否能解决您的内存泄漏问题。