軟體描述
程式可以使用一個引用對象來維持對另外某一對象的引用,所採用的方式是使後者仍然可以被回收器回收。程式還可以安排在回收器確定某一給定對象的可到達性已經更改之後的某個時間得到通知。
包規範
引用對象 封裝了對另一個對象的引用,這樣就可以像其他任何對象一樣檢查和操作引用自身。有三種類型的引用對象,按從強到弱依次為:軟 引用、弱 引用和虛 引用。正如下面定義的那樣,每種類型對應於一個不同的可到達性級別。軟引用適用於實現記憶體敏感的快取,弱引用適用於實現無法防止其鍵(或值)被回收的規範化映射,而虛引用則適用於以某種比 Java 終結機制更靈活的方式調度 pre-mortem清除操作。
每種引用對象類型都是通過抽象的基本 Reference 類的一個子類實現的。其中一個子類的實例封裝了對特定對象的引用,該對象名為指示對象。每個引用對象都提供了獲得和清除該引用的方法。引用對象是不可變的,因此,除了清除操作之外,沒有提供 set 操作。通過添加任何所需的欄位和方法,程式可以為這些子類進一步創建子類,或者可以不加更改地使用這些子類。
通知
在創建引用對象時,通過向引用佇列註冊 一個適當的引用對象,程式可以請求在對象可到達性更改時獲得通知。在垃圾回收器確定引用的可到達性已經更改為對應於引用類型的值之後的某一時間,它會將引用添加到相關的佇列中。此時,該引用被認為是已加入佇列的。通過輪詢或阻塞,直到獲得了引用,程式才可以從佇列中移除引用。引用佇列是通過 ReferenceQueue 類實現的。
已註冊的引用對象及其佇列之間的關係是單向的。也就是說,佇列不會追蹤那些向它註冊的引用。如果一個已註冊的引用本身變得不可到達,則永遠不會將它加入到佇列中。使用引用對象的程式的責任是,確保對象是可達到的,只要程式對其指示對象感興趣。
雖然某些程式會選擇專門使用一個執行緒從一個或多個佇列中移除引用對象並處理它們,但這是絕對沒有必要的。一種通常很有用的策略是:在執行另一個相當頻繁的操作期間檢查引用佇列。例如,使用弱引用來實現弱鍵的哈希表能在每次訪問表時輪詢其引用佇列。這就是 WeakHashMap 類的工作方式。因為ReferenceQueue.poll方法僅僅檢查內部數據結構,此檢查只為哈希表訪問方法增加了很小的系統開銷。
自動清除引用
在將軟引用和弱引用添加到向其註冊的佇列(如果有)之前,回收器將自動清除這些引用。所以,軟引用和弱引用不需要向佇列註冊即可使用,而虛引用則需要這樣做。通過虛引用可到達的對象將仍然保持原狀,直到清除所有這類引用或者它們本身變得不可到達。
可到達性
從最強到最弱,不同的可到達性級別反映了對象的生命周期。在操作上,可將它們定義如下:
如果某一執行緒可以不必遍歷所有引用對象而直接到達一個對象,則該對象是強可到達 對象。新創建的對象對於創建它的執行緒而言是強可到達對象。
如果一個對象不是強可到達對象,但通過遍歷某一軟引用可以到達它,則該對象是軟可到達 對象。
如果一個對象既不是強可到達對象,也不是軟可到達對象,但通過遍歷弱引用可以到達它,則該對象是弱可到達 對象。當清除對某一弱可到達對象的弱引用時,便可以終止此對象了。
如果一個對象既不是強可到達對象,也不是軟可到達對象或弱可到達對象,它已經終止,並且某個虛引用在引用它,則該對象是虛可到達 對象。
最後,當不能以上述任何方法到達某一對象時,該對象是不可到達 對象,因此可以回收此對象。
從以下版本開始:
1.2