首页 > 编程知识 正文

java弱引用的理解与使用,java 软引用和弱引用的作用

时间:2023-05-03 22:05:46 阅读:178473 作者:691

充分理解Java的弱引用

安卓开发探索1 .什么是1. What——弱引用? Java弱引用是指java.lang.ref.WeakReferenceT类。 首先,让我们看一下官方文档的说明。

弱参考对象的存在并不阻止它指向的对象被垃圾回收器回收。 弱引用的最常见用途是实现canonicalizing mappings,如散列表。

假设在垃圾收集器的某个时刻决定对象为弱可达的(weakly reachable)。 也就是说,现在指向它的都是弱参照。 在这种情况下,垃圾收集器会清除指向该对象的所有弱引用,垃圾收集器会将该弱可到达对象标记为“可终止”。 这样,它们以后就会被回收利用。 与此同时或稍后,垃圾回收器会将刚删除的弱引用放入创建弱引用对象时注册的引用队列(Reference Queue)中。

实际上,Java中存在4种参照,它们从强到弱依次是强、软、弱、虚。 让我简单介绍一下弱引用以外的三种引用。

强引用(Strong Reference):使用new创建新对象时返回的引用通常是强引用,如果对象可以通过一系列强引用到达,则它是强可及性的

软引用(Soft Reference):软引用和弱引用的差异在于,如果某个对象是弱引用可达的,则不管当前的存储器是否足够,都会将其回收,而只有在存储器不够大的情况下,软引用可达的对象才会被回收

虚引用(Phantom Reference):虚引用是Java中最弱的引用,但它弱到什么程度呢? 这很脆弱,以至于我们甚至无法获取由虚引用引用的对象。 虚引用存在的唯一作用是,当回收被引用的对象时,它会将虚引用本身添加到引用队列中,并记录被引用的对象已被丢弃。

2. Why——为什么要用弱引用? 考虑一下下面的情景。 现在有一个表示设计为不可扩展的产品的Product类。 这个时候,我想给每个产品追加号码。 一个解决方案是使用HashMapProduct,Integer。 于是发生了问题。 如果Product对象不再需要存在于内存中,例如,如果此产品正在销售,则假设对ProductA的引用为ProductA,ProductA将被赋值为null。 但是,此时不会回收productA过去指向的product对象。 因为很明显HashMap中也引用了它。 所以在这种情况下,如果我们真的想要回收Product对象,仅仅将其强引用代入null是不够的,还必须从HashMap中删除相应的条目。 很明显,“从HashMap中删除不再需要的条目”的工作自己不想做。 您希望告诉垃圾收集器:“如果只有HashMap的key引用了Product对象,则可以回收相应的Product对象。” 很明显,根据前面弱引用的定义,使用弱引用有助于实现这个目的。 您只需要使用对Product对象的弱引用对象作为HashMap的键。

3. How——如何使用弱引用?

both;color:#333333;font-family:Verdana, Arial, Helvetica, sans-serif;font-size:14px;line-height:25.2px;">     拿上面介绍的场景举例,我们使用一个指向Product对象的弱引用对象来作为HashMap的键,只需这样定义这个弱引用对象:

productA = new Product(...);WeakReference<Product> weakProductA = new WeakReference<>(productA);

    现在,若引用对象weakProductA就指向了Product对象productA。那么我们怎么通过weakProduct获取它所指向的Product对象productA呢?很简单,只需要下面这句代码:

Product product = weakProductA.get();

    实际上,对于这种情况,Java类库为我们提供了WeakHashMap类,使用和这个类,它的键自然就是弱引用对象,无需我们再手动包装原始对象。这样一来,当productA变为null时(表明它所引用的Product已经无需存在于内存中),这时指向这个Product对象的就是由弱引用对象weakProductA了,那么显然这时候相应的Product对象时弱可达的,所以指向它的弱引用会被清除,这个Product对象随即会被回收,指向它的弱引用对象会进入引用队列中。 

    下面我们来简单地介绍下引用队列的概念。实际上,WeakReference类有两个构造函数:

WeakReference(T referent) //创建一个指向给定对象的弱引用
WeakReference(T referent, ReferenceQueue<? super T> q) //创建一个指向给定对象并且登记到给定引用队列的弱引用

    我们可以看到第二个构造方法中提供了一个ReferenceQueue类型的参数,通过提供这个参数,我们便把创建的弱引用对象注册到了一个引用队列上,这样当它被垃圾回收器清除时,就会把它送入这个引用队列中,我们便可以对这些被清除的弱引用对象进行统一管理。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。