JVM學習--強引用,軟引用,弱引用,虛引用
文章目錄
JVM學習–強引用,軟引用,弱引用,虛引用
強引用
強引用就是程式碼中通過常規方法建立的物件,比如new,反序列化,反射等方式建立的物件。只要強引用還存在,那麼垃圾收集器就不會回收該物件。
軟引用
如果一個物件只具有軟引用,則記憶體空間足夠,垃圾回收器就不會回收它;如果記憶體空間不足了,就會回收這些物件的記憶體。只要垃圾回收器沒有回收它,該物件就可以被程式使用。軟引用可用來實現記憶體敏感的快取記憶體(下文給出示例)。
軟引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果軟引用所引用的物件被垃圾回收器回收,Java虛擬機器就會把這個軟引用加入到與之關聯的引用佇列中。
Java中使用SoftReference類來實現。
弱引用
弱引用與軟引用的區別在於:只具有弱引用的物件擁有更短暫的生命週期。在垃圾回收器執行緒掃描它所管轄的記憶體區域的過程中,一旦發現了只具有弱引用的物件,不管當前記憶體空間足夠與否,都會回收它的記憶體。不過,由於垃圾回收器是一個優先順序很低的執行緒,因此不一定會很快發現那些只具有弱引用的物件。
弱引用可以和一個引用佇列(ReferenceQueue)聯合使用,如果弱引用所引用的物件被垃圾回收,Java虛擬機器就會把這個弱引用加入到與之關聯的引用佇列中。
Java中使用WeakReference類來實現。
虛引用
“虛引用”顧名思義,就是形同虛設,與其他幾種引用都不同,虛引用並不會決定物件的生命週期。如果一個物件僅持有虛引用,那麼它就和沒有任何引用一樣,在任何時候都可能被垃圾回收器回收。
虛引用主要用來跟蹤物件被垃圾回收器回收的活動。虛引用與軟引用和弱引用的一個區別在於:虛引用必須和引用佇列 (ReferenceQueue)聯合使用。當垃圾回收器準備回收一個物件時,如果發現它還有虛引用,就會在回收物件的記憶體之前,把這個虛引用加入到與之 關聯的引用佇列中。
Java中使用PhantomReference類來實現。
例子
public class ReferenceDemo {
private String name;
public ReferenceDemo(String name) {
this.name = name;
}
public static void main(String[] args) {
//建立強引用物件
ReferenceDemo demo1 = new ReferenceDemo("AA");
ReferenceDemo demo2 = new ReferenceDemo("BB" );
ReferenceDemo demo3 = new ReferenceDemo("CC");
ReferenceDemo demo4 = new ReferenceDemo("DD");
ReferenceDemo demo5 = new ReferenceDemo("FF");
ReferenceDemo demo6 = new ReferenceDemo("EE");
//關聯軟引用
SoftReference<ReferenceDemo> soft1 = new SoftReference<ReferenceDemo>(demo1);
SoftReference<ReferenceDemo> soft2 = new SoftReference<ReferenceDemo>(demo2);
//關聯弱引用
WeakReference<ReferenceDemo> soft3 = new WeakReference<ReferenceDemo>(demo3);
WeakReference<ReferenceDemo> soft4 = new WeakReference<ReferenceDemo>(demo4);
//關聯虛引用
ReferenceQueue<ReferenceDemo> queue = new ReferenceQueue<ReferenceDemo>();
PhantomReference<ReferenceDemo> soft5 = new PhantomReference<ReferenceDemo>(demo5,queue);
// PhantomReference<ReferenceDemo> soft6 = new PhantomReference<ReferenceDemo>(demo6);
//去除強引用
demo1 = null;
demo2 = null;
demo3 = null;
demo4 = null;
System.gc();
print(soft1);
print(soft2);
print(soft3);
print(soft4);
print(soft5);
}
public static void print(Reference<ReferenceDemo> reference){
ReferenceDemo demo = (ReferenceDemo)reference.get();
if(demo == null){
System.out.println(reference.getClass()+" value = null");
}
else{
System.out.println(reference.getClass()+" value = " + demo.getName());
}
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
當 demo3 = null; demo4 = null; 不存在時
輸出
class java.lang.ref.SoftReference value = AA
class java.lang.ref.SoftReference value = BB
class java.lang.ref.WeakReferenceis value = CC
class java.lang.ref.WeakReferenceis value = DD
class java.lang.ref.PhantomReferenceis value = null
當 demo3 = null; demo4 = null; 存在時
輸出
class java.lang.ref.SoftReference value = AA
class java.lang.ref.SoftReference value = BB
class java.lang.ref.WeakReferenceis value = null
class java.lang.ref.WeakReferenceis value = null
class java.lang.ref.PhantomReferenceis value = null
從上面可以看出
- 虛引用關聯的物件是無法獲取到的。
- 軟引用關聯的物件在垃圾回收時,記憶體空間足夠,垃圾回收器就不會回收它。
- 弱引用關聯的物件在垃圾回收時,如果物件的強引用不存在,不管記憶體空間夠不夠,都會被回收。