最近在翻JVM的資料,對於4種引用有很多疑問java
Q1.強引用如何判斷?緩存
Q2.ReferenceQueue的做用?多線程
Q3.4種引用分別的用途?ide
Q4.強引用必定不回收?this
A1.
對於JDK提供的SoftReference/WeakReference/PhantomReference,咱們能夠簡單的經過instanceof
來判斷
可是並無StrongReference,也沒有顯式判斷的API(多是我不會搜索..
目前想到的方法就是用排除的方法,你應該懂我意思線程
A2.
當Reference被回收時,與它關聯的ReferenceQueue會把它入隊,以便真正的回收(.get()不會報錯,那意味着指向的對象被回收,但該Reference的存在依然是實例,而不是null)
(Q.爲何不直接if(ref.get()==null) ref = null?)code
A3.
1.強引用:重要的對象
2.軟引用:有用但不重要的對象,好比緩存,當你面臨OOM時能夠幹掉而不影響正常工做
4.幽靈引用:用於分析GC
3.弱引用:我暫時不太理解用途。。。(由1/2推理得爲沒用又不重要的東西??orz)對象
A4.
已知有一種狀況依然會回收,好比放在某個方法上,若是顯示使用gc()的話仍是會回收的get
A5.
一個彩蛋是發現反射多是隱式使用多線程,待考究it
文章待看:
https://www.jianshu.com/p/f0da6c1af815
直接看代碼
import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.PriorityQueue; import java.util.Scanner; class Xjb { String str; public Xjb(String str) { this.str = str; } public Xjb() { this.str = null; } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("finalize! " + str); } @Override public String toString() { return str.toString(); } } public class Main { public static void print(Object...objs) { Xjb xjb = new Xjb("temp"); for(Object obj:objs) { System.out.println(obj); } } public static void main(String[] args) throws InterruptedException { Xjb str = new Xjb("str"); Reference<Xjb> sr = new SoftReference<Xjb>(new Xjb("sr")); Reference<Xjb> wr = new WeakReference<>(new Xjb("wr")); Reference<Xjb> pr = new PhantomReference<Xjb>(new Xjb("pr"), new ReferenceQueue<>()); Class clazz = str.getClass(); wr = null; // 須要註釋 System.out.println(wr instanceof WeakReference); System.out.println(clazz != null && !clazz.isInstance(new SoftReference<>(new Xjb("tempSr"))) && !clazz.isInstance(new WeakReference<>(new Xjb("tempWr"))) && !clazz.isInstance(new PhantomReference<Xjb>(new Xjb("tempPr"), new ReferenceQueue<>()))); // 疑似反射會隱式調用多線程,有必定機率沒來得及輸出就拋出異常 print(str,sr.get(),wr.get(),pr.get()); System.out.println("GC + SLEEP..."); System.gc(); Thread.currentThread().sleep(2333L); print(str,sr.get(),wr.get(),pr.get()); } }