Java從1.2版本開始引入了4種引用,這4種引用的級别由高到低依次為:強引用 > 軟引用 > 弱引用 > 虛引用。
1. 強引用(StrongReference)
強引用是使用最普遍的引用。如果一個對象具有強引用,那垃圾回收器絕不會回收它。當記憶體空間不足,Java虛拟機甯願抛出OutOfMemoryError錯誤,使程式異常終止,也不會靠随意回收具有強引用的對象來解決記憶體不足的問題。
隻要引用存在,垃圾回收器永遠不會回收。
例如:
Object object = new Object();
String str = "hello";
但是我們也知道,不是所有的強引用在任何時間都是有效的,那jvm如何處理的呢?
如果想中斷強引用和某個對象之間的關聯,可以顯示地将引用指派為null,這樣一來的話,JVM在合适的時間就會回收該對象。
比如Vector類的clear方法中就是通過将引用指派為null來實作清理工作的:
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
Object oldValue = elementData[index];
int numMoved = elementCount - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--elementCount] = null; // Let gc do its work
return (E)oldValue;
}
2. 軟引用(SoftReference)
如果一個對象隻具有軟引用,則記憶體空間足夠,垃圾回收器就不會回收它;如果記憶體空間不足了,就會回收這些對象的記憶體。隻要垃圾回收器沒有回收它,該對象就可以被程式使用。軟引用可用來實作記憶體敏感的高速緩存。
public static void main(String[] args) {
SoftReference sr = new SoftReference(new String("hello"));
System.out.println(sr.get());
}
控制台列印一hello,當記憶體不足時,會回收這部分對象。
3. 弱引用(WeakReference)
弱引用與軟引用的差別在于:隻具有弱引用的對象擁有更短暫的生命周期。在垃圾回收器線程掃描它所管轄的記憶體區域的過程中,一旦發現了隻具有弱引用的對象,不管目前記憶體空間足夠與否,都會回收它的記憶體。不過,由于垃圾回收器是一個優先級很低的線程,是以不一定會很快發現那些隻具有弱引用的對象。
弱引用可以和一個引用隊列(ReferenceQueue)聯合使用,如果弱引用所引用的對象被垃圾回收,Java虛拟機就會把這個弱引用加入到與之關聯的引用隊列中。
public static void main(String[] args) {
WeakReference sr = new WeakReference(new String("hello"));
System.out.println(sr.get());
System.gc();
System.out.println(sr.get());
}
控制台列印:
hello
null
可以看到,隻要顯示調用gc,弱引用對象就被回收。
4. 虛引用(PhantomReference)
形同虛設,與其他幾種引用都不同,虛引用并不會決定對象的生命周期。如果一個對象僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用主要用來跟蹤對象被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個差別在于:虛引用必須和引用隊列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個對象時,如果發現它還有虛引用,就會在回收對象的記憶體之前,把這個虛引用加入到與之 關聯的引用隊列中。
public static void main(String[] args) {
ReferenceQueue queue = new ReferenceQueue();
PhantomReference pr = new PhantomReference(new String("hello"), queue);
System.out.println(pr.get());
}
null