美文网首页@IT·互联网
Java中的四种引用

Java中的四种引用

作者: 我可能是个假开发 | 来源:发表于2023-12-20 09:27 被阅读0次

一、强引用

只有所有 GC Roots 对象都不通过[强引用]引用该对象,该对象才能被垃圾回收
代码中的引用都属于强引用
沿着GC Root的引用链能找到,不会被垃圾回收。

二、软引用

  • 仅有软引用引用该对象时,在垃圾回收后,内存仍不足时会再次触发垃圾回收,回收软引用对象
  • 可以配合引用队列来释放软引用自身

没有直接被强引用所引用
发生了一次垃圾回收,回收完发现内存不够,会把软引用所引用的对象释放。

当软引用所引用的对象被回收之后,软引用本身会进入引用队列。(可以不配合引用队列使用)

/**
 * 演示弱引用
 * -Xmx20m -XX:+PrintGCDetails -verbose:gc
 */
public class WeakReferenceTest {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        //  list --> WeakReference --> byte[]
        List<WeakReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            WeakReference<byte[]> ref = new WeakReference<>(new byte[_4MB]);
            list.add(ref);
            for (WeakReference<byte[]> w : list) {
                System.out.print(w.get()+" ");
            }
            System.out.println();

        }
        System.out.println("循环结束:" + list.size());
    }
}

三、弱引用

  • 仅有弱引用引用该对象时,在垃圾回收时,无论内存是否充足,都会回收弱引用对象
  • 可以配合引用队列来释放弱引用自身

没有直接被强引用所引用,只要发生了垃圾回收,不管内存是否足够,都会把弱引用所引用的对象回收。

当弱引用所引用的对象被回收之后,弱引用本身会进入引用队列。(可以不配合引用队列使用)

引用队列:释放引用本身。

/**
 * 演示软引用
 * -Xmx20m -XX:+PrintGCDetails -verbose:gc
 */
public class SoftReferenceTest {
    private static final int _4MB = 4 * 1024 * 1024;
    public static void main(String[] args) throws IOException {
        //导致oom
        /*List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            list.add(new byte[_4MB]);
        }

        System.in.read();*/
        soft();
    }

    public static void soft() {
        // list --> SoftReference --> byte[]

        List<SoftReference<byte[]>> list = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB]);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());

        }
        System.out.println("循环结束:" + list.size());
        for (SoftReference<byte[]> ref : list) {
            System.out.println(ref.get());
        }
    }
}

清除软引用

/**
 * 演示软引用, 配合引用队列
 */
public class SoftReferenceQueueTest {
    private static final int _4MB = 4 * 1024 * 1024;

    public static void main(String[] args) {
        List<SoftReference<byte[]>> list = new ArrayList<>();

        // 引用队列
        ReferenceQueue<byte[]> queue = new ReferenceQueue<>();

        for (int i = 0; i < 5; i++) {
            // 关联了引用队列, 当软引用所关联的 byte[]被回收时,软引用自己会加入到 queue 中去
            SoftReference<byte[]> ref = new SoftReference<>(new byte[_4MB], queue);
            System.out.println(ref.get());
            list.add(ref);
            System.out.println(list.size());
        }

        // 从队列中获取无用的 软引用对象,并移除
        Reference<? extends byte[]> poll = queue.poll();
        while( poll != null) {
            list.remove(poll);
            poll = queue.poll();
        }

        System.out.println("===========================");
        for (SoftReference<byte[]> reference : list) {
            System.out.println(reference.get());
        }

    }
}

四、虚引用

必须配合引用队列使用,主要配合 BvteBuffer 使用,被引用对象回收时,会将虚引用入队,由Reference Handler 线程调用虚引用相关方法释放直接内存

当创建时,就会关联一个引用队列。
创建bytebuffer的时候,会创建Cleaner虚引用,分配一块直接内存,并且把直接内存地址传递给虚引用对象。
这样在bytebuffer被回收的时候,进入了引用队列的Cleaner虚引用,由ReferenceHandler线程定时执行回收,Cleaner.clean:根据直接内存地址,把直接内存释放(Unsafe.freeMemory)。

必须配合引用队列使用。

五、终结器引用

无需手动编码,但其内部配合引用队列使用,在垃圾回收时,终结器引用入队 (被引用对象暂时没有被回收),再由 Finalizer 线程通过终结器引用找到被引用对象并调用它的 finalize 方法,第二次 GC时才能回收被引用对象

当创建时,就会关联一个引用队列,
Object中finalize()方法,当对象重写了finalize方法,并且没有强引用引用时,可以被回收,虚拟机会创建终结器引用,当对象被垃圾回收时,会把终结器引用加入引用队列,再由FinalizeHandler线程(优先级很低)查看是否存在终结器引用,找到要回收的垃圾对象,调用finalize(),在下一次垃圾回收时,就可以把对象回收了。

相关文章

  • Android使用LeakCanary检测内存泄漏

    Java四种引用 在Java中,有四种不同的引用类型,分别是强引用(Strong Reference)、软引用(S...

  • Java中的四种引用类型

    一、Java中的四种引用类型 JDK 1.2 开始 Java 提供了四种引用类型,分别是强引用、软引用、弱引用、虚...

  • java四种引用类型

    java中得四种引用 Java中有四种引用类型:强引用、软引用、弱引用、虚引用 强引用我们代码中常写,如: Obj...

  • JVM虚拟机读书笔记

    Java VM Runtime Area Java中四种引用: - 强引用(Strong Reference): ...

  • RefenceQueue的源码解析,以及WeakHashMap的

    Java RefenceQueue WeakHashMap 首先介绍Java中的四种引用: 强引用:如Object...

  • Java引用及其应用

    Java 引用分类 Java 中的引用分为四种,具体如下 强引用(StrongReference)强引用是使用最普...

  • Java基础:Java的四种引用

    在Java基础:java虚拟机(JVM)中,我们提到了Java的四种引用。包括:强引用,软引用,弱引用,虚引用。这...

  • Java的引用

    参考链接: Java到底是值传递还是引用传递 Java的四种引用方式 Java中的强引用、软引用、弱引用和虚引用 ...

  • Android面试Java基础篇(四)

    问:Java中四种引用类型 答:四种引用类型分别为 强引用、弱引用、软引用、虚引用 强引用(StrongRefer...

  • 深入理解Java弱引用

    Java中的引用类型 Java中存在四种引用,它们由强到弱依次是:强引用、软引用、弱引用、虚引用。下面我们简单介绍...

网友评论

    本文标题:Java中的四种引用

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