刚刚遇到一位在其Ajax webapp中存在大量内存泄漏问题的客户。所以决定创建以下测试用例来演示该问题:使用jquery append()添加DOM元素似乎泄漏内存?
我在下面 的例子(http://home.orange.nl/jsrosman/)
所使用滴/筛为内存分析情况很简单:我有以下javascript:
<html>
<head>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js">
</script>
</head>
<script type="text/javascript">
var lihtml = "<li class='green'>this is a test text</li>";
function populatelist() {
for (var i = 0; i < 10000; i++) {
$('#listparent').append(lihtml);
}
}
function clearlist() {
$('#listparent').empty();
if (typeof (CollectGarbage) == "function") {
alert('gc');
CollectGarbage();
}
}
/* Alternative clearlist with Remove instead of Empty(), still leaks */
function clearlist() {
/* test remove the parent itself instead of empty below */
$('#listparent').remove();
$('body').append("<ul id='listparent'>");
//$('#listparent').empty();
if (typeof (CollectGarbage) == "function") {
alert('gc');
CollectGarbage();
}
}
/* Edit!, this is the most effective way to release memory so far */
function clearlist() {
$('#listparent').html("");
if (typeof (CollectGarbage) == "function") {
alert('gc');
CollectGarbage();
}
}
</html>
</script>
<body>
<button onclick="javascript:populatelist()">Populate list</button>
<button onclick="javascript:clearlist()">Clear list</button>
<ul id="listparent">
<li>kjjk</li>
</ul>
</body>
</html>
每个单击填充列表后都会附加10000个li元素(表示为文本)。 Clearlist调用jquery empty(),它应该清除DOM子树并使其符合GC条件。
所以我运行这个案例在sIEve和每次我追加新元素的内存使用增加,我从来没有见过它垃圾收集或释放内存。甚至当RAM使用量达到1.5GB时,即使我尝试为IE显式调用GC。
这与我在使用Jquery Ajax获取List数据而不是我的静态内容obv的客户中看到的相同。
我是否以错误的方式创建DOM?有人可以告诉我为什么它不是垃圾收集,我看不到任何其他DOM元素的引用,为什么他们不应该被垃圾收集。另一个奇怪的行为是,当我单击空列表(当调用jquery empty()方法时),有时在sIEve内存中的使用甚至会增加?
如果有人输入我会非常高兴。
更新,我尝试使用$('#listparent')。html(“”),而不是似乎正确释放DOM,至少它是在sIEve中释放。我想这是迄今为止最好的解决方案,尽管我没有解释为什么remove()和empty()似乎不起作用。也许他们只适用于静态添加元素?
只是好奇,你在多个浏览器尝试这种最有效的方法是什么? – Prescott 2010-11-12 12:30:31
没有sIEve只能在IE中使用,还没有试过FFX,主要是因为IE是本系统中用户唯一使用过的浏览器。 – user408346 2010-11-12 12:55:23
其实$('#listparent')。HTML( “”);比empty()和remove()好得多,似乎释放整个DOM。我很无语 – user408346 2010-11-12 12:55:55