1. 程式人生 > >【知識點】垃圾回收之引用計數之迴圈引用

【知識點】垃圾回收之引用計數之迴圈引用

    引用計數常用來說明垃圾收集的工作方式,但似乎從未被應用與任何一種Java虛擬機器中實現。《java程式設計思想》

關於引用計數法,我們可以先看一段wiki上的描述:

As a collection algorithm, reference counting tracks, for each object, a count of the number of references to it held by other objects. If an object’s reference count reaches zero, the object has become inaccessible, and can be destroyed.

When an object is destroyed, any objects referenced by that object also have their reference counts decreased.

作為一種回收演算法,引用計數法記錄著每一個物件被其它物件所持有的引用數。如果一個物件的引用計數為零,那麼該物件就變成了所謂的不可達物件,亦即可以被回收的。

當一個物件被回收後,被該物件所引用的其它物件的引用計數都應該相應減少。

而所謂的迴圈引用(circular referrence)有是什麼意思呢?舉個簡單的例子:

public class MyObject {
    public
Object ref = null; public static void main(String[] args) { MyObject myObject1 = new MyObject(); MyObject myObject2 = new MyObject(); myObject1.ref = myObject2; myObject2.ref = myObject1; myObject1 = null; myObject2 = null; } }

從上面的程式碼可以輕易地發現myObject1與myObject2互為引用,我們知道如果採用引用計數法,myObject1和myObject2將不能被回收,因為他們的引用計數無法為零。

迴圈引用圖示

但是具體是為什麼呢?已上圖為例,當代碼執行完line7時,兩個物件的引用計數均為2。此時將myObject1和myObject2分別置為null,以前一個物件為例,它的引用計數將減1。若要滿足垃圾回收的條件,需要清除myObject2中的ref這個引用,而要清除掉這個引用的前提條件是myObject2引用的物件被回收,可是該物件的引用計數也為1,因為myObject1.ref指向了它。以此類推,也就進入一種死迴圈的狀態。