Java中的四种引用:强、软、弱、虚引用

前言

引用在实际中基本使用的都是强引用,垃圾回收器判断对象是否存在可用的算法:引用计数器算法,可达性分析算法,

引用计数器算法:在对象中添加一个引用计数器,每当对象被引用时,计数器加1,反正计数器减去1,当计数器为0,则不存在引用,垃圾回收的时候就可以回收该对象,但是存在问题无法解决循环依赖的问题。

可达性分析算法:通过一个称为"GC roots"的根对象作为起始节点,从这些节点开始,根据引用关系向下搜索,路径称为引用链,某个对象到根对象没有任何引用链连接,咋这个对象不可达,则该对象不能在使用。

Java的四种引用:

  1. 强引用(Strong Reference)- 最强的引用类型,它们是默认的引用类型。如果一个对象具有强引用,那么垃圾回收器一定不会回收这个对象。

  2. 软引用(Soft Reference)- 当系统内存不够时,垃圾回收器会根据当前内存情况,判断是否回收软引用对象,如果仍然内存不够,才会回收软引用对象。

  3. 弱引用(Weak Reference)- 相对于软引用来说,弱引用关联的对象只能存活到下一次垃圾回收之前,即只要这个对象没有被强引用关联,垃圾回收器就有可能回收它。

  4. 虚引用(Phantom Reference)- 无法通过虚引用访问对象的任何属性或方法,它的作用仅仅是在该对象被回收时收到一个系统通知。

1.强引用

创建一个对象,并将它赋给一个强引用变量。只要该变量存在,对象就不会被垃圾回收。例如:

/**
 *
 * 测试强引用
 */
public class TestStrongReference {
    public static void main(String[] args) {
        String s = new String("hello");
        System.gc();
        System.out.println(s);
    }
}

2.软引用

创建一个对象,并将它赋给一个软引用变量。当系统内存不足时,可能会回收软引用变量指向的对象。例如:

/**
 * 测试软引用
 */
public class TestSoftReference {
    public static void main(String[] args) {
        //创建一个强引用
        String s = new String("hello");
        //添加到软引用
        SoftReference<String> softReference = new SoftReference<>(s);
        s=null;
        //执行垃圾回收
        System.gc();
        //再次获取
        if(softReference !=null ){
            System.out.println(softReference.get());
        }
    }
}

3.弱引用

创建一个对象,并将它赋给一个弱引用变量。只要系统执行完垃圾回收,无论内存是否足够,弱引用变量指向的对象都会被回收。例如:

/**
 * 弱引用
 */
public class TestWeakReference {
    public static void main(String[] args) {
        WeakReference<String> weakReference = new WeakReference<>(new String("hello"));
        //执行垃圾回收
        System.out.println("执行垃圾回收之前");
        System.out.println(weakReference.get());
        System.gc();
        System.out.println("执行垃圾回收之后:");
        System.out.println(weakReference.get());

    }
}

4.虚引用

创建一个对象,并将它赋给一个虚引用变量。当系统执行完垃圾回收时,无论内存是否足够,虚引用变量指向的对象都会被回收。例如:

/**
 * 虚引用
 */
public class TestPhantomReference {
    public static void main(String[] args) throws InterruptedException {
        ReferenceQueue<String> referenceQueue = new ReferenceQueue<>();
        PhantomReference<String> phantomReference = new PhantomReference<>(new String("hello"), referenceQueue);
        System.gc();
        System.out.println(referenceQueue.remove().get());
    }
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘同学要加油呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值