1. 程式人生 > >JAVA中的強引用、軟引用(SoftReference)、弱引用(WeakReference)和幽靈引用(PhantomReference)

JAVA中的強引用、軟引用(SoftReference)、弱引用(WeakReference)和幽靈引用(PhantomReference)

JAVA語言提供了四種引用型別:
強引用、軟引用(SoftReference)、弱引用(WeakReference)和幽靈引用(PhantomReference),與引用密切相關的,還有一個引用佇列ReferenceQueue。


1、強引用
(1)回收時機:強引用不會被GC回收,當記憶體空間不足,Java虛擬機器寧願丟擲OutOfMemoryError錯誤,使程式異常終止,也不會靠隨意回收具有強引用的物件來解決記憶體不足問題。
(2)eg:
Object obj = new Object();這裡的obj引用便是一個強引用。
2、軟引用
(1)回收時機:如果記憶體空間足夠,垃圾回收器就不會回收它,如果記憶體空間不足了,就會回收這些物件的記憶體,但也不一定會回收全部的軟引用,更傾向於回收那些在記憶體中停留時間比較久的軟引用。
(2)軟引用可用來實現記憶體敏感的快取記憶體。 (3)軟引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果軟引用所引用的物件被垃圾回收,Java虛擬機器就會把這個軟引用加入到與之關聯的引用佇列中。
eg:
Object object=new Object();
ReferenceQueue<Object> queue=new ReferenceQueue<Object>();
SoftReference<Object> srf=new SoftReference<Object>(object, queue);
System.out.println(srf.get());//[email protected],返回強引用物件
//srf指向的物件持有強引用和軟引用,不會被回收,因此不會加入到queue中
System.out.println(queue.poll());//null

// 清除強引用,觸發GC  
object = null;  
System.gc();  
    
//該物件現在只有一個軟引用
System.out.println(srf.get()); //
[email protected]
,返回強引用物件   //即使發生gc,該物件也不一定會被回收加入queue,只有記憶體空間不足才會回收軟引用物件,因此queue中獲取不到物件 //發生gc到將物件加入到queue中需要一段時間,這裡sleep等待,方便下面poll方法(非阻塞)獲取值 Thread.sleep(200); System.out.println(queue.poll()); //null

3、弱引用

(1)回收時機:弱引用的物件擁有更短暫的生命週期。在垃圾回收器執行緒掃描它所管轄的記憶體區域的過程中,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體。不過,由於垃圾回收器是一個優先順序很低的執行緒, 因此不一定會很快發現那些只具有弱引用的物件。 
(2)弱引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果弱引用所引用的物件被垃圾回收,Java虛擬機器就會把這個弱引用加入到與之關聯的引用佇列中。
eg:
		Object object=new Object();
		ReferenceQueue<Object> queue=new ReferenceQueue<Object>();
		WeakReference<Object> srf=new WeakReference<Object>(object, queue);
		System.out.println(srf.get());//返回該弱引用的強引用,[email protected]
		//srf指向的物件持有強引用和弱引用,不會被回收,因此不會加入到queue中
		System.out.println(queue.poll());//null
		
		// 清除強引用,觸發GC  
		object = null;  
		System.gc();  
	    
		//該物件現在只有一個弱引用,發生gc,回收弱引用物件,srf為空
		System.out.println(srf.get()); //null
	  
	    
		//發生gc到將物件加入到queue中需要一段時間,這裡sleep等待,方便下面poll方法(非阻塞)獲取值
		Thread.sleep(200);
		System.out.println(queue.poll());  //[email protected]


4、虛引用
(1)虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用佇列(ReferenceQueue)聯合使用。
(2)當垃圾回收器回收一個物件時,如果發現它還有虛引用,就會把這個虛引用加入到與之關聯的引用佇列中。程式可以通過判斷引用佇列中是否已經加入了虛引用,來了解被引用的物件是否將要被垃圾回收。如果程式發現某個虛引用已經被加入到引用佇列,那麼就可以在所引用的物件的記憶體被回收之前採取必要的行動。由於Object.finalize()方法的不安全性、低效性,常常使用虛引用完成物件回收前的資源釋放工作。