關於4種引用

最近在翻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());
        
    }
}
相關文章
相關標籤/搜索