浅谈Java中强软弱虚引用

什么是强软弱虚引用?为什么要搞出来这四种引用?什么情况下可以用到这四种引用呢?本文主要探讨这三个问题!

1基本概念
强引用:在Java程序中通过调用构造器方法或者反射的方式创建出来的对象后通过一个引用指向它,并且在程序运行的过程中,可以通过引用链可以获取到这个对象,那么就可以说此处有一个强引用!比如如下两种情况:

1)通过构造器创建对象后,有一个引用指向它

//调用构造器创建对象,num指向这个对象
Integer num = new Integer(“2”);
2)通过引用链可以获取到对象,且不为空

//通过引用链获取到对象,程序运行过程任意一个环节不会为null
List<Integer> intList = new ArrayList<>();
intList.add(new Integer("2"));
Map<String,List<Integer>> map = new HashMap<>();
map.put("aa",intList);
System.out.println(map.get("aa").get(0));
强引用和其他引用相比,最大的特点就是:垃圾收集器始终不会将其回收,如果系统内存不够在创新新的对象,那么就会抛出OutOfMemoryError!

除了强引用,其他的引用都需要借助java.lang.ref包下的抽象类Reference的子类来进行包装操作了!在java.lang.ref包下,Reference类有3个具体的实现类,SoftReference、WeakReference和PhantomReference,分别表示软引用、弱引用和虚引用!

软引用:使用SoftReference包装的对象就是软引用!代码如下:

//创建一个软引用,包含一个对象
SoftReference<Integer> soft = new SoftReference<>(new Integer("23456"));
//软引用包含的对象可以通过get()获取到
Integer num = soft.get();
需要注意的是,使用软引用包装的对象不能通过其他引用的方式获取到,否则就不是软引用了,软引用中的对象可以通过get方法获取出来使用!

弱引用:使用WeakReference包装的对象就是弱引用!代码如下:

//创建一个弱引用,包含一个对象
WeakReference<Integer> weak = new WeakReference<>(new Integer("23456"));
//弱引用包含的对象可以通过get()获取到
Integer weakNum = weak.get();
和软引用相同,使用弱引用包装的对象不能通过其他引用的方式获取到,否则就不是弱引用了,弱引用中的对象也可以通过get方法获取出来使用!

虚引用:使用PhantomReference包装的对象就是虚引用,和软引用、弱引用不同的是虚引用不能直接放在PhantomReference中,而是必须放在一个ReferenceQueue队列中,代码如下:

//创建一个虚引用,包含一个对象
ReferenceQueue<Integer> intRq = new ReferenceQueue<>();
PhantomReference<Integer> phantom = new PhantomReference<>(new Integer("23456"),intRq);
//弱引用包含的对象可以通过get()获取到
Integer phantomNum = phantom.get();
同上,使用虚引用包装的对象不能通过其他引用的方式获取到,否则就不是虚引用了,与上述几种引用不同的是虚引用通过get方法并不能获取对象!

2几种引用的使用场合
为何要搞出来这几种引用呢?简单介绍下这几种引用的作用就可以明白这几种应用的使用场合了!

我们知道垃圾回收器会把不在使用的对象回收以释放内存,垃圾回收器如何判断是不是需要接着使用呢?这里就是根据引用来判断的,如果是强引用的对象,那么系统就不会回收这个对象占用的内存!如果有一些大对象,希望在系统内存够用的时候不要回收,在系统内存不够的时候可以回收,或者有些对象希望系统可以允许其存在直到下一次垃圾回收,此时就可以使用上述的几种引用方式来包装这些不同回收策略的对象了!

对于强引用,系统即使抛出OutOfMemoryError也不会进行垃圾回收!

对于软引用,系统只是在内存不够用的时候将其使用的内存回收,测试代码如下:

//创建一个软引用,包含一个对象
SoftReference<Integer> soft = new SoftReference<>(new Integer("23456"));
//提醒系统进行一个垃圾收集
System.gc();
System.out.println(soft.get() == null);
打印false,说明软引用中的对象并没有被回收!软引用适合于做内存敏感的高速缓存,内存够用的时候就保留,不够用就回收!

对于弱引用,系统只要进行垃圾收集就会将其使用的内存回收,测试代码如下:

//创建一个弱引用,包含一个对象
WeakReference<Integer> weak = new WeakReference<>(new Integer("23456"));
//提醒系统进行一次垃圾回收
System.gc();
System.out.println(weak.get() == null);
打印true,说明弱引用中的对象被回收了!弱引用是为实现规范映射而设计的,具体可以看WeakHashMap的使用方法!     

对于虚引用,创建出来以后即使不进行垃圾回收也拿不到里面包装的对象了!

//创建一个虚引用,包含一个对象
ReferenceQueue<Integer> intRq = new ReferenceQueue<>();
PhantomReference<Integer> phantom = new PhantomReference<>(new Integer("23456"),intRq);
Integer phantomNum = phantom.get();
System.out.println(phantomNum == null);
打印true,说明虚引用获取不到包装的对象!虚引用用以调度回收前的清理工作!

通过上述几种引用的介绍,可以知道这几种引用是为垃圾回收提供了更大的灵活性,通过使用不同的引用用户就可以使用不同的垃圾回收策略!
--------------------- 
作者:撒欢嘞啦 
来源:CSDN 
原文:https://blog.csdn.net/weixin_38810239/article/details/79548942 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值