Java虛擬機有5個不同級別的對象的可達性。
●強可達(Strongly reachable)
如果一個對象可以被一些線程直接使用而不用通過其他引用對象(reference objects),那么它就是強可達。一個新創建的對象對創建它的線程來講就是強可達的。
這是我們知道并且一直在使用的引用類型(譯注:通常被new出來的對象都是強可達的,他們的引用就是強引用)。任何通過強引用所使用的對象(在一個活動線程中)都不會被GC回收。
●軟可達(Softly reachable)
如果一個對象沒有強可達性,但是它可以通過一個軟引用(soft reference.)來使用,那么它就具有軟可達性。
只有當系統需要更多內存時,GC才會回收具有軟可達性的對象。在內存不足前,GC保證一定回收軟可達的對象。
有可能我們會在代碼中寫下這么幾行:“嘿,我想要把一些數據保存在內存中。但只要JVM快把內存用光的時候,就可以直接將這些東西回收并將這些引用置為null。我會在代碼里面處理這種情況。”關于軟引用(SoftReference)何時應該被回收的算法依賴于不同的JVM發行版本。它往往是一個跟引用(reference)的使用頻率和使用間隔有關的函數。
軟引用可用來實現內存敏感的高速緩存.但是你懂的,具體的行為還是得依賴于JVM。并且多少跟內存回收機制有關,保障很少并且跟具體的JVM發行版本有關。為了緩存的可靠(及其他更多特性),大多數人都會選用像Ehcache而不是用軟引用實現自己的緩存。但在一些場合,使用軟引用確實可以讓代碼非常優雅、簡潔。
●弱可達(Weakly reachable)
如果一個對象既沒有強可達性,也沒有軟可達性,但是它可以通過一個弱引用(weak reference)來使用,那么他就具有弱可達性。當弱引用指向的弱可達對象沒有其他的引用,那么這個對象就會被回收。
弱引用不能阻止垃圾回收機制清理他指向的引用。弱引用最常見的使用情景是通過WeakHashMap。它是一種簡單地將對象的生命周期跟Map中對象的索引域(key)綁定的方式。只有當WeakHashMap中的Key是強可達,也就是WeakHashMap中的數據域(Data域)的對象,在應用程序的其他地方有別的引用的時候,它里面的值才不會被回收。一旦應用程序中沒有其他對WeakHashMap中對象的引用,那么它的所有的key就會變成弱可達,不需要用戶的額外干預,所有WeakHashMap中的對象都會被清除。這是一種優雅地防止內存泄露的方式。
●虛可達(Phantom reachable)
如果一個對象既沒有強可達性,也沒有軟可達性、弱可達性,他已經被終結(finalized),并且有一些虛引用(phantom reference)指向它,那么它就具有虛可達性。
虛引用(PhantomReference)指向的對象是不能被取回使用的。它的get()方法永遠返回null,所以它有什么用呢?
所有的引用類型都允許在構造函數中指定一個引用隊列(ReferenceQueue)。從語義上講一個虛引用(PhantomReference)以什么方式、何時入隊讓對象終結(finalization)以一種更好、更健壯的方式進行。
●不可達(Unreachable)
當一個對象不能通過以上的方式指向,那么這個對象就變得不可達,并因此適合被回收。
本文翻譯自:
Garbage Collection, Reference types and Reachability – Strong, Soft, Weak, Phantom, Unreachable6
文章列表