to lantersen(蓝水仁--剑锋于砺出,梅香至苦寒!~) 对于“dt = new Object();//如果被置空,如果继续按“show”将会报三个方法都未定义;”来说,一个新的Object显然没有定义m1,m2,m3,结果可以理解。 但我的问题相当于当一个双向链表的头指针赋为null的时候链表的节点是否都会被释放,似乎与你的提法有点不同
一般来说,只要这个对象没有被任何变量体引用到,那它就会被系统自动回收掉。 比如说我直接 new node() 而不把这个实例赋给一个变量的话,那在这个代码段执行完毕之后,这个实例也就会自动被系统回收。但若是 var a = new node() 这样赋过值的话,只要这个变量 a 与这个实例之间的引用关系没有破坏,这个实例就会一直存在于内存之中。所以单看你的代码,当 obj = null 之后这个实例应该被回收掉的。
如楼主 Crabshai(Crabshai) 的第二个回复来说,你的 for 循环只是不断地给 next.child 等属性赋值,赋一次值就“冲”掉前一个赋值,类似于“熊掰玉米”,那被挤掉的那个对象立时成了“丧家之犬”,被系统回收掉了,到最后,obj 对象里只剩一份 new node() 而非 50000 份,所以你的这个测试没有什么意义。
dt.m1 = 'menthod0';
dt.m2 = function () {return 'menthod1';};
dt.m3 = 'menthod3'; function g()
{
alert(dt.m1+' , '+dt.m2+' , '+dt.m3+' ');
return true;
}
function d()
{
dt = null;//如果被置空,如果继续按“show”将会报错;
dt = new Object();//如果被置空,如果继续按“show”将会报三个方法都未定义;
return true;
}
</script>
</HEAD><BODY>
<INPUT TYPE="button" NAME="" onclick="g();return true;" value="show">
<INPUT TYPE="button" NAME="" onclick="d();return true;" value="Delete">
</BODY>
</HTML>
对于“dt = new Object();//如果被置空,如果继续按“show”将会报三个方法都未定义;”来说,一个新的Object显然没有定义m1,m2,m3,结果可以理解。
但我的问题相当于当一个双向链表的头指针赋为null的时候链表的节点是否都会被释放,似乎与你的提法有点不同
<script language=javascript>
function HBchild()
{
this.hbhbhbhbhb1021="hbhbhbhbhb1021"
}function HB()
{
var str=new Array();
for(var i=0;i<50000;i++)
{
str[i]="this.child"+i+"=new HBchild();"
}
eval(str.join(""))
}var obj=new HB();
alert("天外水火");
obj=null;
alert("天外水火");
</script>
在弹出第一个框之前cpu 100%,内存一直在加,第二个的时候不减,而且一直不减,直到最后关掉。
“在IE窗体被最小化时,IE将会主动调用一次CollectGarbage()函数。这使得IE窗口在最小化之后,内存占用会有明显改善。”hbhbhbhbhb1021(天外水火(我要多努力)) 的测试代码我试验了一下,事实上是回收掉了。
可以稍作修改能看得更清楚:
var obj=new HB();
alert("天外水火"); obj=null;
setTimeout(CollectGarbage, 1); //alert("天外水火");
关掉对话框后内存明显减少了。另外:你的代码只是关于一个对象,不是两个或多个对象之间相互引用产生的问题。不过你的方法给了我很大启发,可以写个测试来试验一下
{
this.parent;
this.child
}var obj=new node;
var next=obj;for (var i=0; i<50000; i++ )
{
next.child=new node;
next.child.parent=next;
next=next.child;
}alert("done");obj=null;
next=null;setTimeout(CollectGarbage, 1);</script></body></html>
比如说我直接 new node() 而不把这个实例赋给一个变量的话,那在这个代码段执行完毕之后,这个实例也就会自动被系统回收。但若是 var a = new node() 这样赋过值的话,只要这个变量 a 与这个实例之间的引用关系没有破坏,这个实例就会一直存在于内存之中。所以单看你的代码,当 obj = null 之后这个实例应该被回收掉的。
<SCRIPT LANGUAGE="JavaScript">
<!--
function node()
{
this.parent;
this.child
}
node.prototype.dispose=function()
{
delete this.parent;
delete this.child;
};
function c2()
{
this.child=new node;
this.child.parent=this;
}
c2.prototype.dispose=function()
{
this.child.dispose();
delete this.child;
};var obj=new c2;//释放
obj.dispose();
obj = null;//-->
</SCRIPT>
不过我觉得大量节点的释放还是系统来做好,毕竟遍历每个节点是比较慢的,而且还要写额外的代码,呵呵
/**
谢谢meizz(梅花雪)的答复,让我更清晰的了解了垃圾回收的概念。
不过我觉得大量节点的释放还是系统来做好,毕竟遍历每个节点是比较慢的,而且还要写额外的代码,呵呵
***/
'不过我觉得大量节点的释放还是系统来做好'
W:如果光把这些交给系统来做的话,系统肯定是没你了解你的项目,自然什么时应该释,什么时候该删除什么属性,如果回收不及时,自然增加了资源的开销,所以本人还是比较认可尽可能的手动去释放一些变量(delete)
<script language=javascript>
function HBchild()
{
this.hbhbhbhbhb1021="hbhbhbhbhb1021"
}function HB()
{
var str=new Array();
for(var i=0;i<50000;i++)
{
str[i]="this.child"+i+"=new HBchild();"
}
eval(str.join(""))
}
delete str;
var obj=new HB();
alert("天外水火");for(var i=0;i<50000;i++)
{
var objChild=eval("obj.child"+i);
delete objChild.hbhbhbhbhb1021;
delete objChild;
}obj=null;
setTimeout("CollectGarbage();", 1);
alert("天外水火");
</script>