关于4种引用

最近在翻JVM的资料,对于4种引用有不少疑问

Q1.强引用如何判断?

Q2.ReferenceQueue的作用?

Q3.4种引用分别的用途?

Q4.强引用一定不回收?

A1.
对于JDK提供的SoftReference/WeakReference/PhantomReference,我们可以简单的通过instanceof来判断
但是并没有StrongReference,也没有显式判断的API(可能是我不会搜索..
目前想到的方法就是用排除的方法,你应该懂我意思

A2.
当Reference被回收时,与它关联的ReferenceQueue会把它入队,以便真正的回收(.get()不会报错,那意味着指向的对象被回收,但该Reference的存在依然是实例,而不是null)
(Q.为什么不直接if(ref.get()==null) ref = null?)

A3.
1.强引用:重要的对象
2.软引用:有用但不重要的对象,比如缓存,当你面临OOM时可以干掉而不影响正常工作
4.幽灵引用:用于分析GC
3.弱引用:我暂时不太理解用途。。。(由1/2推理得为没用又不重要的东西??orz)

A4.
已知有一种情况依然会回收,比如放在某个方法上,如果显示使用gc()的话还是会回收的

A5.
一个彩蛋是发现反射可能是隐式使用多线程,待考究

文章待看:
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());
        
    }
}

猜你喜欢

转载自www.cnblogs.com/caturra/p/10781410.html