關於java對象的四種引用類型,網上博客真是五花八門,所以抽時間總結一下。歡迎各位大蝦指正。
首先,希望大家理解一組名詞,就不會像我一樣懵逼了。
強引用(Strong Reference)、軟引用(Soft Reference)、弱引用(Weak Reference)、虛引用(Phantom Reference)。這 4 種引用的強度依次減弱。
1.強引用(Strong Reference):
如果一個對象具有強引用,它就不會被垃圾回收器回收。即使當前內存空間不足,JVM也不會回收它,而是拋出 OutOfMemoryError 錯誤,使程序異常終止。如果想中斷強引用和某個對象之間的關聯,可以顯式地將引用賦值為null,這樣一來的話,JVM在合適的時間就會回收該對象
Object obj = new Object(); //只要obj還指向Object對象,Object對象就不會被回收 obj = null; //手動置null
2.軟引用(Soft Reference):
在使用軟引用時,如果內存的空間足夠,軟引用就能繼續被使用,而不會被垃圾回收器回收。只有在內存不足時,系統則會回收軟引用對象,如果回收了軟引用對象之后仍然沒有足夠的內存,才會拋出內存溢出異常。
在 JDK1.2 之后,用java.lang.ref.SoftReference類來表示軟引用。
使用場景:
這種特性常常被用來實現緩存技術,比如網頁緩存,圖片緩存等。
3.弱引用(Weak Reference):
具有弱引用的對象擁有的生命周期更短暫。因為當 JVM 進行垃圾回收,一旦發現弱引用對象,無論當前內存空間是否充足,都會將弱引用回收。不過由於垃圾回收器是一個優先級較低的線程,所以並不一定能迅速發現弱引用對象。
在 JDK1.2 之后,用 java.lang.ref.WeakReference 來表示弱引用。
使用場景:
在靜態內部類中,經常會使用虛引用。例如:一個類發送網絡請求,承擔 callback 的靜態內部類,則常以虛引用的方式來保存外部類的引用,當外部類需要被 JVM 回收時,不會因為網絡請求沒有及時回應,引起內存泄漏。
4.虛引用(Phantom Reference):
顧名思義,就是形同虛設,如果一個對象僅持有虛引用,那么它相當於沒有引用,在任何時候都可能被垃圾回收器回收。
虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用隊列(ReferenceQueue)聯合使用。當垃圾回收器准備回收一個對象時,如果發現它還有虛引用,就會在回收對象的內存之前,把這個虛引用加入到與之關聯的引用隊列中。
在 JDK1.2 之后,用 PhantomReference 類來表示。
使用場景:
jdk中直接內存的回收就用到虛引用,由於jvm自動內存管理的范圍是堆內存,而直接內存是在堆內存之外(其實是內存映射文件,自行去理解虛擬內存空間的相關概念),所以直接內存的分配和回收都是有Unsafe類去操作,java在申請一塊直接內存之后,會在堆內存分配一個對象保存這個堆外內存的引用,這個對象被垃圾收集器管理,一旦這個對象被回收,相應的用戶線程會收到通知並對直接內存進行清理工作。