在Nicholas Zakas的書中,他解釋了在Javascript中使用引用計數進行垃圾回收時循環引用的問題。他用下面的例子:JavaScript參考計數中的循環引用
function problem(){
var objectA = new Object();
var objectB = new Object();
objectA.someOtherObject = objectB;
objectB.anotherObject = objectA;
}
解釋說,這兩個對象將永遠不會分配給它們的內存被釋放,因爲它們具備的功能裏面他們兩個引用。我想澄清一下這是如何工作的。
顯然,每個對象有兩個引用。第一個對象同時指向objectA
和objectB.anotherObject
。所以每個對象的引用計數是2.但是當函數退出時會發生什麼?這在書中沒有真正描述。他說,只要對該值的引用被另一個值覆蓋,引用計數就會減少。我認爲這意味着:
function problem(){
var objectA = new Object();
var objectB = new Object();
objectA.someOtherObject = objectB;
objectB.anotherObject = objectA;
objectA.someOtherObject = objectA; //<-- that if I were to do this,
//the reference count of the first object (A)
//would become 3, and 1 for the second object (B).
}
但是,當函數退出時會發生什麼?據我瞭解,objectA
和objectB
和它們各自的引用對象的屬性都將被銷燬,因此,這兩個對象的引用計數將減少2.我沒有看到Zacas的「循環引用問題」談論。有人能解釋他想說什麼嗎?
是否還有一個仍然依賴於引用計數的實現?根據https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management,這些對象將*在所有現代實現中被銷燬。 – rici
@rici不,引用計數 - 至少在其天真形式 - 並不完全是因爲這個缺陷和[需要改進](https://en.wikipedia.org/wiki/Reference_counting#Dealing_with_reference_cycles)。正如MDN所述,所有現代引擎都使用一些標記和掃描實現。然而,引用計數仍然可以應用於已知不是或不是非常循環的特定局部結構,因爲它的簡單性可能更好。 – Bergi
是的,這就是我的想法。我認爲OP中提到的這本書有些過時,因爲我認爲MSIE的早期版本遭受了這個問題。但我的印象是現代ES實現將在本例中正確地垃圾收集這兩個對象。我的理解是,問題是在ref-counting環境中用循環引用來解釋問題,但肯定值得一提的是,問題在實踐中不再存在;沒有必要手動中斷參考週期,這與您仍然會發現浮動的建議相反。 – rici