美文网首页JAVA进阶
java中的四种引用——强、软、弱、虚

java中的四种引用——强、软、弱、虚

作者: 那些年搬过的砖 | 来源:发表于2021-05-09 11:58 被阅读0次

一、强引用

强引用比较好理解,我们编程中绝大部分对象都是强引用,在GC过程中,如果存在强引用对象,即便发生OOM,也不会被回收

Object m = new Object();

二、软引用

在堆内存不足时,jvm的GC会回收软引用对象

public class SoftReferenceTest {
    public static void main(String[] args) {
        SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 1024 * 10]);
        System.out.println(m.get());
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(m.get());

        byte[] b = new byte[1024 * 1024 * 15];
        System.out.println(m.get());
    }
}

上述代码在内存中的引用关系如下图所示



假如我们指定-Xmx20M,然后运行

[B@2503dbd3
[B@2503dbd3
null

从运行结果可以看出,第一次和第二次输入对象不为空,即便中间发生了一次gc,第二次依然不为空,是因为内存足够,所以不会被回收,但是当第三次new一个15M的对象时,总空间15+10=25M,超出堆内存总大小(20M),这时jvm会回收调软引用对象。

软引用的使用场景:缓存(比如缓存一些图片文件)

三、弱引用

把上面代码稍作修改,将软引用改为弱引用,其他保持不变

public class WeakReferenceTest {
    public static void main(String[] args) {
        WeakReference<byte[]> m = new WeakReference<>(new byte[1024 * 1024 * 10]);
        System.out.println(m.get());
        System.gc();
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(m.get());

        byte[] b = new byte[1024 * 1024 * 15];
        System.out.println(m.get());
    }
}

运行结果

[B@2503dbd3
null
null

从运行结果可以看出,第二次输出时,即便内存足够,依然会被回收。

结论:垃圾回收器会直接回收弱引用对象,和软引用的区别就是不管内存是否充裕都会被回收。

ThreadLocal就是用到了弱引用技术,关于ThreadLocal可以参见另一篇博文
ThreadLocal

四、虚引用

public class PhantomReferenceTest {
    private static final List<Object> LIST = new LinkedList<>();
    private static final ReferenceQueue<M> QUEUE = new ReferenceQueue<>();
    public static void main(String[] args) {
        PhantomReference<M> pr = new PhantomReference<>(new M(), QUEUE);
        //虚引用输出为空
        System.out.println(pr.get());
    }
}

java官方的解释:
Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed. Phantom references are most often used for scheduling pre-mortem cleanup actions in a more flexible way than is possible with the Java finalization mechanism.
虚引用指向的对象有可能会被重新访问到,常用于对象死亡后的清理操作。


在NIO场景中,堆内存中的对象有可能会访问堆外内存的对象,当堆内存被GC回收时,堆外内存也应该释放,JVM是怎么知道堆外内存是否可回收呢,所以java提供了一种钩子机制,这种机制就是虚引用。

应用场景:管理直接内存(堆外内存)

相关文章

  • JAVA四种引用(强引用,弱引用,软引用,虚引用)

    JAVA四种引用(强引用,弱引用,软引用,虚引用) [toc] 参考:Java 的强引用、弱引用、软引用、虚引用四...

  • java四种引用类型

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

  • 强、软、弱、虚引用的区别和使用

    原文阅读:强、软、弱、虚引用的区别和使用 Java提供了四种级别的应用类型:强引用、软引用、弱引用及虚引用。那么这...

  • Android面试Java基础篇(四)

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

  • Java的四种对象引用类型

    Java的四种对象引用类型:强引用、弱引用、软引用、虚引用。 强引用(StrongReference): 强引用是...

  • Java中的四种引用类型

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

  • 深入理解Java弱引用

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

  • Java基础:Java的四种引用

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

  • JAVA 基础 之 引用类型

    Java中的引用类型包含四种:强,软,弱,虚 强引用 强引用就是我们平时使用的最多的引用类型,比如:Object ...

  • Java 四种引用类型

    Java中四种引用包括:强引用,软引用,弱引用,虚引用。 强引用: 只要引用存在,垃圾回收器永远不会回收 //可直...

网友评论

    本文标题:java中的四种引用——强、软、弱、虚

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