Java引用类型:强引用、软引用、弱引用、软引用
标签搜索
侧边栏壁纸
  • 累计撰写 6 篇文章
  • 累计收到 75 条评论

Java引用类型:强引用、软引用、弱引用、软引用

xiaodong
2020-06-28 / 14 评论 / 728 阅读 / 正在检测是否收录...

jdk从1.2开始,把对象的引用分为四个类型,这四种引用类型从生命周期从长到短依次是:强引用、软引用、弱引用、虚引用。

Java引入这四种引用类型的目标主要有两个:
一个是可以让程序员通过代码的方式控制对象的生命周期;
一个是有利于jvm进行垃圾回收。

强引用

程序中最普遍的默认对象引用,也是程序开发中最常用的引用类型。JVM的垃圾回收期在任何时候都不会回收强引用。即使当内存空间不足抛出内存溢出(OOM),也不会回收具有强引用的对象来释放内存。我们可以显式的赋值对象为null,来告诉gc该对象不存在引用,这时gc就可以回收这个对象,但具体什么时候收集还是要取决于gc的算法。

比如ArraryList类的clear方法中就是通过将引用赋值为null来实现清理工作

/**
 * Removes all of the elements from this list.  The list will
 * be empty after this call returns.
 */
public void clear() {
    modCount++;

    // clear to let GC do its work
    for (int i = 0; i < size; i++)
        elementData[i] = null;

    size = 0;
}

软引用

软引用用来描述一些有用但不是必需的对象,在Java中用java.lang.ref.SoftReference类来表示。对于软引用关联着的对象,只有在内存不足的时候JVM才会回收该对象。因此,这一点可以很好地用来解决OOM的问题,并且这个特性很适合用来实现缓存:比如网页缓存、图片缓存等。

比如下面的代码,即使obj赋值为null,软引用关联对象在内存充足的情况不会被回收。

public class TestSoftReference {
    public static void main(String[] args) {
        Obj obj = new Obj("SoftReference");
        SoftReference<Obj> sr = new SoftReference<>(obj);
        obj = null;
        System.gc();
        System.out.println(sr.get().getName());
    }
}

@Data
@AllArgsConstructor
class Obj {
    private String name;
}

运行结果:

SoftReference

弱引用

弱引用用来描述一些非必须的对象。弱引用相比于软引用拥有更短的生命周期,当JVM运行垃圾回收的时候,不论内存是否充足,都会回收只被弱引用对象关联的对象。在java中,用java.lang.ref.WeakReference类来表示。

比如下面的代码,obj赋值为null后,弱引用关联的对象会在执行垃圾回收后被回收。

public class TestWeakReference {
    public static void main(String[] args) {
        Obj obj = new Obj("WeakReference");
        WeakReference<Obj> wr = new WeakReference<>(obj);
        System.out.println(wr.get().getName());
        System.out.println("----------------");

        obj = null;
        System.out.println(wr.get().getName());
        System.out.println("----------------");

        // 推荐gc来回收
        System.gc();
        System.out.println(wr.get().getName());
    }
}

运行结果:

WeakReference
----------------
WeakReference
----------------
Exception in thread "main" java.lang.NullPointerException
    at com.xiao.temporary.TestRefrence.main(TestRefrence.java:25)

虚引用

顾名思义,就是形同虚设,即对对象而言是无感知的。与其他几种引用类型不同,虚引用不会影响和决定对象的生命周期。在java中用java.lang.ref.PhantomReference类表示。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。

虚引用主要用来跟踪对象被垃圾回收的活动(即对象是否存活的监控)。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列(ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

比如下面的代码,通过是否入列ReferenceQueue可以判断对象是否被回收。

public class TestPhantomReference {
    public static void main(String[] args) {
        Obj obj = new Obj("PhantomReference");
        ReferenceQueue<Obj> referenceQueue = new ReferenceQueue<>();
        PhantomReference<Obj> pr = new PhantomReference<>(obj, referenceQueue);
        // 永远为null
        System.out.println("pr.get:" + pr.get());
        // 是否入队,和是否被回收有关
        System.out.println("pr.isEnqueued:" + pr.isEnqueued());
        // poll一下referenceQueue中的对象看看
        System.out.println("referenceQueue.poll:" + referenceQueue.poll());
        System.out.println("----------------");

        obj = null;
        System.out.println("pr.get:" + pr.get());
        System.out.println("pr.isEnqueued:" + pr.isEnqueued());
        System.out.println("referenceQueue.poll:" + referenceQueue.poll());
        System.out.println("----------------");

        // 推荐gc来回收
        System.gc();
        System.out.println("pr.get:" + pr.get());
        System.out.println("pr.isEnqueued:" + pr.isEnqueued());
        System.out.println("referenceQueue.poll:" + referenceQueue.poll());
    }
}

运行结果:

pr.get:null
pr.isEnqueued:false
referenceQueue.poll:null
----------------
pr.get:null
pr.isEnqueued:false
referenceQueue.poll:null
----------------
pr.get:null
pr.isEnqueued:true
referenceQueue.poll:java.lang.ref.PhantomReference@610455d6

总结

引用类型被垃圾回收时间用途生存时间
强引用从来不会对象的一般状态JVM停止运行时
软引用内存不足时对象缓存内存不足时
弱引用jvm垃圾回收时对象缓存gc运行后
虚引用未知未知未知
4

评论 (14)

取消
  1. 头像
    abbyahkzja
    Windows 10 · Google Chrome

    博主真是太厉害了!!!

    回复
  2. 头像
    eomvevxmcm
    Windows 10 · Google Chrome

    看的我热血沸腾啊

    回复
  3. 头像
    ezeaitbmox
    Windows 10 · Google Chrome

    看的我热血沸腾啊https://www.ea55.com/

    回复
  4. 头像
    jtmrtkvtew
    Windows 10 · Google Chrome

    哈哈哈,写的太好了https://www.cscnn.com/

    回复
  5. 头像
    vfwjwuonzc
    Windows 10 · Google Chrome

    你的文章让我感受到了不一样的风景,谢谢分享。 http://www.55baobei.com/pQYrKbVDeM.html

    回复
  6. 头像
    muvuuggrew
    Windows 10 · Google Chrome

    看到你的文章,我仿佛感受到了生活中的美好。 https://www.4006400989.com/qyvideo/91841.html

    回复
  7. 头像
    mthgedcabv
    Windows 10 · Google Chrome

    你的文章让我感受到了快乐,每天都要来看一看。 https://www.yonboz.com/video/49165.html

    回复
  8. 头像
    ujfjoemgyd
    Windows 10 · Google Chrome

    你的文章内容非常专业,让人佩服。 http://www.55baobei.com/zTMWsNYO0e.html

    回复
  9. 头像
    ljpbbamxkw
    Windows 10 · Google Chrome

    你的文章让我感受到了快乐,每天都要来看一看。 https://www.4006400989.com/qyvideo/89745.html

    回复
  10. 头像
    mpflapvweg
    Windows 10 · Google Chrome

    你的文章内容非常专业,让人佩服。 https://www.4006400989.com/qyvideo/15271.html

    回复
  11. 头像
    yujvutrqpg
    Windows 10 · Google Chrome

    你的文章让我感受到了快乐,每天都要来看一看。 http://www.55baobei.com/jZs5WetZOe.html

    回复
  12. 头像
    lmvidcieql
    Windows 10 · Google Chrome

    独特的构思和新颖的观点,让这篇文章在众多作品中脱颖而出。

    回复
  13. 头像
    hsiarmwsdx
    Windows 10 · Google Chrome

    2025年10月新盘 做第一批吃螃蟹的人coinsrore.com
    新车新盘 嘎嘎稳 嘎嘎靠谱coinsrore.com
    新车首发,新的一年,只带想赚米的人coinsrore.com
    新盘 上车集合 留下 我要发发 立马进裙coinsrore.com
    做了几十年的项目 我总结了最好的一个盘(纯干货)coinsrore.com
    新车上路,只带前10个人coinsrore.com
    新盘首开 新盘首开 征召客户!!!coinsrore.com
    新项目准备上线,寻找志同道合 的合作伙伴coinsrore.com
    新车即将上线 真正的项目,期待你的参与coinsrore.com
    新盘新项目,不再等待,现在就是最佳上车机会!coinsrore.com
    新盘新盘 这个月刚上新盘 新车第一个吃螃蟹!coinsrore.com

    回复
  14. 头像

    华纳圣淘沙公司开户新手教程

    零基础学会(183-8890-9465薇-STS5099)
    华纳圣淘沙公司开户

    华纳圣淘沙公司开户保姆级教程(183-8890-9465薇-STS5099)

    一步步教你开通华纳圣淘沙公司账户(183-8890-9465薇-STS5099)

    华纳圣淘沙公司开户分步图解

    首次开户必看:(183-8890-9465薇-STS5099)
    华纳圣淘沙全攻略

    华纳圣淘沙公司开户实操手册(183-8890-9465薇-STS5099)
    华纳圣淘沙开户流程视频教程

    手把手教学:(183-8890-9465薇-STS5099)
    华纳圣淘沙公司开户

    华纳圣淘沙公司开户完全指南(183-8890-9465薇-STS5099)

    回复