美文网首页
Java四种引用

Java四种引用

作者: ythmilk | 来源:发表于2021-01-12 16:08 被阅读0次

强引用-如果对象还可达,发生OOM也不回收

Java大部分对象都是强引用的,对于强引用的对象,超过其作用域或者显示的复为null,则可能在垃圾回收时将其回收掉。

软引用(SoftReference)-内存不足时回收

在即将发生OOM时,进行回收
多用于缓存

public class SoftReferenceTest {
    public static void main(String[] args) {
        String str=new String("str");
        SoftReference softReference = new SoftReference(str);
        System.out.println(str);
        str=null;
        System.out.println(str);
        System.out.println(softReference.get());
    }
}

输出

str
null
str

上面强引用str,已经设为不可达,但是软引用还是可以获取到对象的。

弱引用(WeakReference)—发现就回收

弱引用的对象只能存活到下一次垃圾回收之前
类似软引用,都适合做缓存使用

见ThreadLoacl的使用,见WeakHashMap

虚引用(PhantomReference)—对象回收跟踪

虚引用和没有引用一样,随时都可能被回收
虚引用用于垃圾回收的通知感知
虚引用的get方法获取的都是null

public class PhantomReferenceTest {
    private static String abc = new String("abc0");
    static boolean isRun = true;
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<String> referenceQueue = new ReferenceQueue<String>();
        new Thread() {
            @Override
            public void run() {
                while (isRun) {
                    PhantomReference obj = (PhantomReference) referenceQueue.poll();
                    if (obj != null) {
                        System.out.println("full gc " + obj);
                        Field rereferent = null;
                        try {
                            rereferent = Reference.class
                                    .getDeclaredField("referent");
                            rereferent.setAccessible(true);
                            Object result = rereferent.get(obj);
                            System.out.println("full gc " + result);
                            isRun = false;
                        } catch (NoSuchFieldException | IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }

                }
            }
        }.start();
        PhantomReference<String> abcWeakRef = new PhantomReference<String>(abc, referenceQueue);
        abc = null;
        Thread.currentThread().sleep(3000);
        System.gc();
        Thread.currentThread().sleep(3000);
    }
}

上述例子是一个根据虚引用感知被垃圾回收的例子。
通过反射获取父类的reference字段,获取引用的值,真正不推荐这样用,了解就好,基本不会使用。


软引用、弱引用、虚引用都可以传一个ReferenceQueue用来监控实现Reference的引用对象的垃圾回收。

可以在外部对这个queue进行监控。即如果有对象即将被回收,那么相应的reference对象就会被放到这个queue里。就可以感知到这个类要被回收了。

相关文章

网友评论

      本文标题:Java四种引用

      本文链接:https://www.haomeiwen.com/subject/onteaktx.html