Java-四種引用和ReferenceQueue簡述
熟悉Java的四種引用和ReferenceQueue,可以幫助解決快取和記憶體洩漏等問題。
Reference
GC只清理物件所佔的記憶體,如DB、檔案等資源需要手動清理。
Reference決定了它所指向的物件的生命週期,從而決定了記憶體的使用量
影響物件的生命週期從長到短的排序:強引用、軟引用、弱引用、虛引用
除了強引用,其他三種引用對物件的生命週期的影響,都是指在釋放強引用後。
StrongReference
預設的引用方式就是強引用
當強引用物件佔用的記憶體足夠多時,JVM就會丟擲OutOfMemory
引用
Object obj = new Object();
new 表示建立物件,= 表示使用強引用指向該物件
釋放
obj = null;
場景
無特殊情況時
SoftReference
引用
Object obj = new Object();
SoftReference<Object> sr = new SoftReference<Object>(obj);
釋放
當物件只有軟引用指向它,且記憶體緊張時
場景
可用於資料快取等
WeakReference
引用
Object obj = new Object();
WeakReference<Object> wr = new WeakReference<Object>(obj);
釋放
當物件只有弱引用指向它時(即不影響物件生命週期)
場景
操作或依附該物件,卻不能影響其正常被回收時
PhantomReference
引用
Object obj = new Object();
ReferenceQueue<Object> rq = new ReferenceQueue<Object>();
PhantomReference<Object> pr = new PhantomReference<Object>(obj, rq);
釋放
當物件只有虛引用指向它時(即不影響物件生命週期)
場景
結合ReferenceQueue追蹤物件是否已經被回收
PhantomReference的get()結果必定為null。
SoftReference和WeakReference的get()可能為null。
ReferenceQueue
SoftReference、WeakReference的constructor都有ReferenceQueue的過載
ReferenceQueue主要是用於監聽Reference所指向的物件是否已經被垃圾回收。
當大量使用Reference時,雖然Reference指向的物件可能被回收了,但Reference本身也是個物件,所以也需要回收。這時就需要使用ReferenceQueue了。
當SoftReference或WeakReference的get()加入ReferenceQueue或get()返回null時,僅是表明其指示的物件已經進入垃圾回收流程,此時物件不一定已經被垃圾回收。
當PhantomReference加入ReferenceQueue時,則表明物件已經被回收。