#### Java四種引用包括強(qiáng)引用彼棍,軟引用,弱引用膳算,虛引用
1. 強(qiáng)引用
? ? ? ? 只要引用存在座硕,垃圾回收器永遠(yuǎn)不會(huì)回收
? ? ? ? Object obj = new Object();? ? ? ? //可直接通過(guò)obj取得對(duì)應(yīng)的對(duì)象 如obj.equels(new Object());
? ? ? ? 而這樣 obj對(duì)象對(duì)后面new Object的一個(gè)強(qiáng)引用,只有當(dāng)obj這個(gè)引用被釋放之后涕蜂,對(duì)象才會(huì)被釋放掉坎吻,這也是我們經(jīng)常所用到的編碼形式。
2. 軟引用
? ? ? ? 非必須引用宇葱,內(nèi)存溢出之前進(jìn)行回收,可以通過(guò)以下代碼實(shí)現(xiàn)
? ? ? ? Object obj = new Object();
? ? ? ? SoftReference<Object> sf = new SoftReference<Object>(obj);
? ? ? ? obj = null;
? ? ? ? sf.get(); //有時(shí)候會(huì)返回null
? ? ? ? 這時(shí)候sf是對(duì)obj的一個(gè)軟引用刊头,通過(guò)sf.get()方法可以取到這個(gè)對(duì)象黍瞧,當(dāng)然,當(dāng)這個(gè)對(duì)象被標(biāo)記為需要回收的對(duì)象時(shí)原杂,則返回null印颤;
? ? ? ? 軟引用主要用戶實(shí)現(xiàn)類似緩存的功能,在內(nèi)存足夠的情況下直接通過(guò)軟引用取值穿肄,無(wú)需從繁忙的真實(shí)來(lái)源查詢數(shù)據(jù)年局,提升速度;當(dāng)內(nèi)存不足時(shí)咸产,自動(dòng)刪除這部分緩存數(shù)據(jù)矢否,從真正的來(lái)源查詢這些數(shù)據(jù)。
3. 弱引用
? ? ? ? 第二次垃圾回收時(shí)回收脑溢,可以通過(guò)如下代碼實(shí)現(xiàn)僵朗、
? ? ? ? Object obj = new Object();
? ? ? ? WeakReference<Object> wf = new WeakReference<Object>(obj);
? ? ? ? obj = null;
? ? ? ? wf.get();//有時(shí)候會(huì)返回null
? ? ? ? 弱引用是在第二次垃圾回收時(shí)回收,短時(shí)間內(nèi)通過(guò)弱引用取對(duì)應(yīng)的數(shù)據(jù)屑彻,可以取到验庙,當(dāng)執(zhí)行過(guò)第二次垃圾回收時(shí),將返回null社牲。
? ? ? ? 弱引用主要用于監(jiān)控對(duì)象是否已經(jīng)被垃圾回收器標(biāo)記為即將回收的垃圾粪薛,可以通過(guò)弱引用的isEnQueued方法返回對(duì)象是否被垃圾回收器標(biāo)記。
WeakReference(T referent, ReferenceQueue<? super T> q):與上面的構(gòu)造方法比較搏恤,多了個(gè)ReferenceQueue违寿,在對(duì)象被回收后湃交,會(huì)把弱引用對(duì)象,也就是WeakReference對(duì)象或者其子類的對(duì)象陨界,放入隊(duì)列ReferenceQueue中巡揍,注意**不是被弱引用的對(duì)象**,被弱引用的對(duì)象已經(jīng)被回收了菌瘪。
```
? ? ? ? Object obj = new Object();
ReferenceQueue queue = new ReferenceQueue();
WeakReference<Object> wrf = new WeakReference<>(obj,queue);
boolean enqueued = wrf.isEnqueued();
System.out.println("回收之前 WeakReference:"+wrf);
System.out.println("回收之前 Object:"+wrf.get());
obj = null;
System.gc();
System.runFinalization(); //讓gc立刻執(zhí)行
Reference poll = null;
while(( poll = queue.poll() ) != null){
System.out.println("ReferenceQueue 中"+poll);
}
boolean enqueued1 = wrf.isEnqueued();
System.out.println("回收之后 Object:"+wrf.get());
```
```
回收之前 WeakReference:java.lang.ref.WeakReference@6f94fa3e
回收之前 Object:java.lang.Object@5e481248
ReferenceQueue 中java.lang.ref.WeakReference@6f94fa3e
回收之后 Object:null
```
```
? ? ? ? String key = new String("abc");
String value = new String("value");
WeakHashMap<String, String> weakHashMap = new WeakHashMap<>();
weakHashMap.put(key,value);
System.out.println("gc before weakHashMap size:"+weakHashMap.size() );
key = null;
System.gc();
System.runFinalization();
System.out.println("gc after weakHashMap size:"+weakHashMap.size() );
```
```
gc before weakHashMap size:1
gc after weakHashMap size:0
```
4. 虛引用
? ? ? ? 垃圾回收時(shí)回收腮敌,無(wú)法通過(guò)引用取到對(duì)象值,可以通過(guò)如下代碼實(shí)現(xiàn)
? ? ? ? Object obj = new Object();
? ? ? ? PhantomReference<Object> pf = new PhantomReference<Object>(obj);
? ? ? ? obj=null;
? ? ? ? pf.get();//永遠(yuǎn)返回null
? ? ? ? 虛引用是每次垃圾回收的時(shí)候都會(huì)被回收俏扩,通過(guò)虛引用的get方法永遠(yuǎn)獲取到的數(shù)據(jù)為null糜工,因此也被成為幽靈引用。
? ? ? ? 虛引用主要用于檢測(cè)對(duì)象是否已經(jīng)從內(nèi)存中刪除录淡。
```
? ? ? ? Object obj1 = new Object();
System.out.println(obj1);
ReferenceQueue<Object> refQueue = new ReferenceQueue<>();
PhantomReference<Object> phantom = new PhantomReference(obj1,refQueue);
System.out.println(phantom);
System.out.println(refQueue.poll());
obj1 = null;
System.gc();
System.runFinalization();
System.out.println(phantom.get()); // 由于這個(gè)返回永遠(yuǎn)是null
Reference ref = null;
while((ref = refQueue.poll()) != null){
Field rereferent = Reference.class
.getDeclaredField("referent");
rereferent.setAccessible(true);
Object result = rereferent.get(ref);
System.out.println("gc will collect:"
+ result.getClass() + "@"
+ result.hashCode() + "\t"
+ result);
}
```
##### 立刻手動(dòng)執(zhí)行GC回收捌木,
```
System.gc();
System.runFinalization();
```