2016-05-29 51 views
1

我只是在javascript中进行一些实验。 我的问题:在下面的代码片段中,“第二”和“第三”是垃圾回收吗?这在处理链接列表时可能特别有用。指向null的JavaScript链对象是否会被垃圾收集?

var first = {} 
var second = first; 
var third = second; 

first = null; 
+0

简答:是的。你能猜出原因吗? –

+0

该对象仍然可以通过第二和第三,所以不,它不会得到GC。 – MinusFour

+1

@JanDvorak - 那是不对的。只要'second'和'third'仍然在某个范围内(即使只是在关闭中),该对象仍然具有实时引用。 –

回答

3

secondthird还是要你的对象引用,因此还不能进行垃圾回收。

当你这样做:

var first = {}; 
var second = first; 

您的变量second不必first参考。它引用了与first指向的相同对象。所以,现在你有两个相同的变量,都有一个对同一个对象的引用。

当您设置:

first = null; 

所有,你也很清楚在first变量引用到该对象。该对象本身并未受到任何影响。而且,对你的问题最重要的是,变量second完全没有受到影响,所以它仍然有对该对象的引用,因此它不能被垃圾收集。

对于JavaScript中的一个对象进行垃圾收集,在代码中可达代码中的任何地方都不能对该对象进行实时引用。只要second仍然是可访问的变量,它指向的对象不能被垃圾收集。


如果你知道像C++的指针语言,那么你可以像你在

var first = {}; 

不喜欢把一个指向你的对象变成first想转让的。 first实际上不包含对象本身。该对象自身存在。 first只包含指向该对象的一个​​点。

然后,当你这样做:

var second = first; 

创建另一个变量,你会得到从first指针并把同样的点的副本到second。现在你有两个完全独立的变量,都包含一个指向你的对象的指针。请记住,在它自己的存在的对象,所以当你然后做:

first = null; 

所有你正在做的是清除指针first。该对象仍然存在,并且second仍包含指向它的指针。由于仍然存在活动指针,因此该对象不会被垃圾收集。


对于要被垃圾收集你的对象,你要么必须包含对对象的引用,以清除在所有三个变量:

var first = {} 
var second = first; 
var third = second; 

first = null; 
second = null; 
third = null; 

或者,你将需要所有三个变量超出范围,所以变量本身被垃圾收集。

+0

MDN提到了一个较旧的“参考计数”算法和一个更新的“标记和扫描”。该算法在参照物体方面是否重要? [内存管理](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management) – Duco

+0

@Duco - 这些只是垃圾收集器可能用于跟踪活动引用的实现方法。垃圾收集背后的目标是相同的。好的,可靠的和快速的垃圾收集器并不容易,尤其是当对象数量变大并且它们之间的关系变得复杂时,以及您希望能够收集部分作用域并且没有任何循环引用问题时。除此之外,浏览器还有两个收集对象空间(Javascript和DOM),当Javascript引用DOM对象时,它们可以相互关联)。 – jfriend00

+0

感谢您的帮助!这似乎有点反直观,虽然可以理解的是,对象是通过引用来处理,并且只能通过引用来处理。也许我会使用一个getter方法来使链表自己null,如果前一个项目是null ...嗯。再次感谢。 – Duco