美文网首页
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