<html>
<head>
<script language="javascript">
var arr = new Array();
function c()
{
var div = document.createElement("DIV");
document.body.appendChild(div);
div.innerHTML = '<input type="button" value="从内部删除" onclick="f()"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div>';
arr.push(div);
abcd.innerText = arr.length;
}function f()
{
var tmp = arr.pop();
while(tmp!=null)
{
document.body.removeChild(tmp);
tmp.childNodes[1].style.filter = "";//发现style的filter是个特殊的东西 需要手动释放一下
tmp = arr.pop();
}
abcd.innerText = arr.length;
this.onclick = null;
}function g()
{
CollectGarbage();
}</script>
</head>
<body><input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
</body>
</html>
<head>
<script language="javascript">
var arr = new Array();
function c()
{
var div = document.createElement("DIV");
document.body.appendChild(div);
div.innerHTML = '<input type="button" value="从内部删除" onclick="f()"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div>';
arr.push(div);
abcd.innerText = arr.length;
}function f()
{
var tmp = arr.pop();
while(tmp!=null)
{
document.body.removeChild(tmp);
tmp.childNodes[1].style.filter = "";//发现style的filter是个特殊的东西 需要手动释放一下
tmp = arr.pop();
}
abcd.innerText = arr.length;
this.onclick = null;
}function g()
{
CollectGarbage();
}</script>
</head>
<body><input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
</body>
</html>
对于remove的对象来说,它还是存在的,可以append回来:<html>
<head>
<script language="javascript">
var arr = new Array();
var currentNum=0;
function c()
{
if(arr[currentNum]) document.body.appendChild(arr[currentNum]);
else{
var div = document.createElement("DIV");
document.body.appendChild(div);
div.innerHTML = '<input type="button" value="从内部删除" onclick="f()"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div>';
arr.push(div);
}
currentNum++;
abcd.innerText = currentNum;
}function f()
{
for (var i=currentNum-1;i>-1;i--)
{
document.body.removeChild(arr[i]);
}
currentNum=0;
abcd.innerText = currentNum;
}function g()
{
CollectGarbage();
}</script>
</head>
<body><input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
</body>
</html>
function fFixMl(oEle)
{ // shawl.qiu code, void return
if(!oEle)oEle=document.body;
var atr=oEle.attributes;
if(atr)
for(var i=0, j=atr.length; i<j; i++)
if(typeof oEle[atr[i].name]=='function')oEle[atr[i].name]=null;
if(oEle.childNodes)
for(var i=0, j=oEle.childNodes.length; i<j; i++)
arguments.callee(oEle.childNodes[i]);
} // end function fFixMl(oEle)
function fCkBrs()
{// shawl.qiu script, return integer
switch (navigator.appName)
{
case 'Opera': return 2;
case 'Netscape': return 3;
default: return 1;
}
} // end function fCkBrs
点击“从内部删除”按钮的时候,所以造成了资源相互引用,所以CollectGarbage()认为资源仍然被占用,所以不去释放资源。
备注:因为是在IE上发现的这个问题,火狐下没有发现类似情况,所以我准备给微软写信,大家支持我一下,有了新的进展我会及时贴到这个帖子后面。希望大家继续讨论问题。
<head>
<script language="javascript">
var currentNum=0;
function c()
{
var div = document.createElement("DIV");
document.getElementById("aaaaa").appendChild(div);
div.innerHTML = '<input type="button" value="从内部删除" onclick="f()"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div>';
currentNum++;
abcd.innerText = currentNum;
}function f()
{
document.getElementById("aaaaa").innerHTML="";
currentNum=0;
abcd.innerText = currentNum;
}function g()
{
CollectGarbage();
}</script>
</head>
<body><input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
<div id="aaaaa">
</div>
</body>
</html>
只要在卸载将onclick事件置空就可以完全释放内存了
我测试添加20次 删除 再添加20次 内存都是98M左右 而且不用使用CollectGarbage()方法function f()
{
var tmp = arr.pop();
while(tmp!=null)
{
document.body.removeChild(tmp);
tmp.onclick = null;//onclick事件也最好置空一下
tmp = arr.pop();
}
abcd.innerText = arr.length;
}
http://topic.csdn.net/u/20070501/09/eeb7bb7b-ebe9-432d-a496-87a645e75cfd.html
我把你贴的代码原样测试了一下,发现问题依旧。
removeChild 之后我又调用了 CollectGarbage(); 所以内存应该得到释放了,因为点击“删除”按钮(参考测试1)后就可以正常释放内存。
不好意思,小弟才疏学浅,没看明白兄弟写的什么意思。麻烦哪位朋友给讲解一下
和你之前描述的情况一样,我测试了一下,只要与arr脱离了关系又removeChild了,应该可以正常释放了,因为没有了任何引用,即使这个内存不释放也不能再次使用了,所以调用CollectGarbage(); 应该正常释放的。另外,参考我之前说过的理由:
removeChild 之后我又调用了 CollectGarbage(); 所以内存应该得到释放了,因为点击“删除”按钮(参考测试1)后就可以正常释放内存。
js和DOM对象占用的内存很多
IE下createElement的DOM对象无论如何应当挂到documentElement之下的节点中去
否内进程里的内存白丢
别指望被回收月の影 12:07:11
所以最好不要临时生成 不用的DOM对象月の影 12:07:48
我不知道为什么,只能理解为
对于进程来说DOM对象申请的资源是永久的
否内进程里的内存白丢
别指望被回收
即使挂上去了,也不会被回收只是不挂,心理不平衡:D
按照你所讲的,设置了tmp.onclick = null;
我测试了,结果问题仍然没有改变。
----
楼主的出发点:确认这是个IE的bug,可以向IE报告。
JK的出发点:碰到IE的bug,只能当作是踩到了便便,绕过就成。---另:给IE报bug的古道热肠值得鼓励.
连续点开20个层然后一起关闭,最后释放内存,这样确实可以释放一些内存,但是反复几次发现内存会持续上涨。
如果你打开一个关闭一个立即释放内存,反复重复上述过程,就会发现内存几乎没有一点释放的
大家测试的时候,观察windows 任务管理器的 “PF使用”,而不是“进程”选项卡。
加20个层时内存测试开始PF:806MB
第一次 98.224k
第二次 98.444k
3: 98.544k
4: 98.676k
5: 98.680k
6: 98.752k
7: 98.748k
8: 98.752k
9: 98.628k
10: 98.752k
11: 98.756k
12: 98.752k
13: 98.748k
14: 98.684k
15: 98.764k
16: 98.768k
17: 98.784k
18: 98.768k
19: 98.716k
20: 98.716k20次之后PF:807MB
你的怎么涨的这么慢?我的每添加一个层PF就增加4M
我使用的是IE6
我看明白你的代码了,增加你的代码后,内存依然没有被释放掉
var arr = [];
function c() {
document.body.innerHTML += '<div id="tdiv_'+ arr.length + '">'
+ '<div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div>'
+ '</div>';
arr[arr.length] = "tdiv_" + arr.length;
}function f() {
while(tmp = arr.pop()) {
tmp = document.getElementById(tmp);
if (tmp.outerHTML) tmp.outerHTML = "";
else tmp.parentNode.removeChild(tmp);
}
}
</script>
<input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
而且内存也没涨 最终稳定在98,7XX左右
没使用CollectGarbage();
说明大部份内存已经被释放了 可能有部分其他变量没有被释放而已.
问题已经很明了了 如果没有别的问题 我也就此结束回复了.
这样问题貌似解决了...流程: 添加 -> 从内部删除 -> 释放内存...
<html>
<head>
<script language="javascript">
var arr = new Array();
function c()
{
var div = document.createElement("DIV");
var Main = document.getElementById("Main");
document.body.appendChild(div);
div.innerHTML = '<input type="button" value="从内部删除" onclick="f();"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div>';
arr.push(div);
abcd.innerText = arr.length;
}function f()
{
var tmp = arr.pop();
while(tmp!=null)
{
// for(var i = tmp.childNodes.count-1; i >=0 ; i--)
// {
// tmp.removeChild(tmp.childNodes[i]);
// }
document.body.removeChild(tmp);
tmp = arr.pop();
}
abcd.innerText = arr.length;
fFixMl();
}function g()
{
fFixMl();
} function fFixMl(oEle)
{ // shawl.qiu code, void return
if(!oEle)oEle=document.body;
var atr=oEle.attributes;
if(atr)
for(var i=0, j=atr.length; i <j; i++)
if(typeof oEle[atr[i].name]== 'function ')oEle[atr[i].name]=null;
if(oEle.childNodes)
for(var i=0, j=oEle.childNodes.length; i <j; i++)
arguments.callee(oEle.childNodes[i]);
} // end function fFixMl(oEle)
function fCkBrs()
{// shawl.qiu script, return integer
switch (navigator.appName)
{
case 'Opera ': return 2;
case 'Netscape ': return 3;
default: return 1;
}
} // end function fCkBrs
</script>
</head>
<body><input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="Main">
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
</div>
</body>
</html>
第一个是坏消息,我的电脑中木马了,刚刚才恢复好,上来看看帖子,回头再次进行了测试,奇怪的是有了新的发现,就是主帖子上说的那段代码有了新的情况,具体情况看下面的例子。
第二个消息是好消息,27楼(btbtd)兄弟的代码通过测试,内存释放很快。详细测试结果:执行此行代码“fFixMl();”能够更快的释放内存,大概从第2或3次开始就会即时释放内存。如果不执行此行代码,大概需要消耗70M左右才会释放内存(注意:不是之前的不释放情况了,不知道是否与系统重做(插件什么的都没有了)有关系)。<html>
<head>
<script language="javascript">
var arr = new Array();
function c()
{
var div = document.createElement("DIV");
document.body.appendChild(div);
div.innerHTML = '<input type="button" value="从内部删除" onclick="f()"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div>';
arr.push(div);
abcd.innerText = arr.length;
} function f()
{
var tmp = arr.pop();
while(tmp!=null)
{
// for(var i = tmp.childNodes.length-1; i >= 0 ; i--)
// {
// tmp.removeChild(tmp.childNodes[i]);
// }
document.body.removeChild(tmp);
tmp = arr.pop();
}
abcd.innerText = arr.length;
fFixMl();//我的测试结果:执行此行代码能够更快的释放内存。如果不执行此行代码,大概需要消耗70M左右才会释放内存。否则大概从第2或3次开始就会即时释放内存。
} function g()
{
fFixMl();
} function fFixMl(oEle)
{ // shawl.qiu code, void return
if(!oEle)
{
oEle=document.body;
}
var atr=oEle.attributes;
if(atr)
{
for(var i=0, j=atr.length; i<j; i++)
{
if(typeof(oEle[atr[i].name])=='function') ;//oEle[atr[i].name]=null;
}
}
if(oEle.childNodes)
{
for(var i=0, j=oEle.childNodes.length; i<j; i++)
{
arguments.callee(oEle.childNodes[i]);
}
}
} // end function fFixMl(oEle)
</script>
</head>
<body><input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
</body>
</html>
但HTML元素内的function成员是个例外 如果你不手动设置成null 就算卸载了这个HTML元素 IE也不会去主动释放它 包括function内引用到的所有内存都不会被释放btbtd的方法确实是个万全之策,不过效率比较低.毕竟要遍历所有HTML节点的所有属性.
建议LZ如果是你自己写的程序 最好手动的去卸载这些function 好像你上面的程序 只要加个onclick=null就行了
同学,这个方法你可以测试下
把卸载属性那个去掉也会释放内存的(大多情况)我很好奇啊它明明只是跑了一遍,就把内存给释放了?由于跑的时候帮助浏览器检测到了垃圾?(很可能的说)
另外
这个问题,根本就和function的释放没有直接关系你可以把那个按钮去掉也不会释放的
主要的原因是filter,不过实在不理解跑一变为什么就可以释放。还有。。即使不跑的话JK前辈说到。用innerHTML就可以释放。。并且我测试用outerHTML也可以释放。并且很效率
只要指定一个容器, document.getElementById(x) 就可以专项专对
ie下单个元素的成员就多达120多.遍历一次的时间消耗不是小数何况还要判断成员的类型.
当然在使用各种UI框架时却会遇到各种情况,好像ext和yahooUI都没有专门的针对对象的内存卸载方法. 对付这种情况最好的就是用btbtd的通用方法完成释放工作.
因此你的那个稍微改一下就不会出现内存泄露了,也不需要调用CollectGarbage方法
while(typeof tmp != 'undefined')
{
tmp.innerHTML = "";
document.body.removeChild(tmp);
tmp = arr.pop();
}
insertAdjacentHTML!<html>
<head>
<script language="javascript">if(typeof(HTMLElement)!="undefined" && !window.opera)
{
HTMLElement.prototype.insertAdjacentHTML=function(where, html)
{
var e=this.ownerDocument.createRange();
e.setStartBefore(this);
e=e.createContextualFragment(html);
this.insertAdjacentElement(where,e);
};
HTMLElement.prototype.insertAdjacentElement=function(where, e)
{
switch (where)
{
case 'beforeBegin': this.parentNode.insertBefore(e, this);break;
case 'afterBegin': this.insertBefore(e, this.firstChild); break;
case 'beforeEnd': this.appendChild(e); break;
case 'afterEnd':
if(!this.nextSibling) this.parentNode.appendChild(e);
else this.parentNode.insertBefore(e, this.nextSibling); break;
}
};
};
var arr = new Array();
function c()
{
var id = "mm_"+ (new Date().getTime().toString(36));
document.getElementById("mm").insertAdjacentHTML("beforeEnd", '<div id="'+ id +'"><input type="button" value="从内部删除" onclick="f()"/><div style="position:absolute;top:110;left:110;width:1000px;height:1000px;-moz-opacity:0.07;filter:alpha(opacity=7);background-color:#000000"></div></div>')
arr[arr.length] = document.getElementById(id);
abcd.innerHTML = arr.length;
}function f()
{
arr.length = 0;
document.getElementById("mm").innerHTML = "";
}function g()
{
CollectGarbage();
}</script>
</head>
<body><input type="button" value="添加" onclick="c();" />
<input type="button" value="删除" onclick="f();" />
<input onclick="g()" type="button" value="释放内存" />
<div id="abcd"></div>
典型的 半透明层 内存泄露问题:<br />
测试:(必须在IE下测试才能发现问题)<br />
1、依次执行“添加”“删除”“释放内存”,如此反复多次,发现内存可以正常释放。<br />
2、依次执行“添加”“从内部删除”“释放内存”,如此反复多次,发现内存泄露无限制增长。
<div id="mm"></div>
</body>
</html>
//Meizz
var e = this.ownerDocument.createRange();
e.setStartBefore(this);
e = e.createContextualFragment(html);
this.insertAdjacentElement(where, e);
};
HTMLElement.prototype.insertAdjacentElement = function(where, e) {
//Meizz
switch (where) {
case 'beforeBegin' : this.parentNode.insertBefore(e, this); break;
case 'afterBegin' : this.insertBefore(e, this.firstChild); break;
case 'beforeEnd' : this.appendChild(e); break;
case 'afterEnd' :
if (!this.nextSibling) this.parentNode.appendChild(e);
else this.parentNode.insertBefore(e, this.nextSibling);
break;
}
};
你那个树能不能修修, 用Opera 9+ 根本看不了导航,
btbtd最好研究一下各个js框架 很有帮助的
还有FF提供了大量的对象原型供开发者扩展 真的很方便.
现在各个浏览器有什么东西基本上我可以倒背出来...
系统化的东西, 我现在可以一个人写个CMS系统...