手动将引用排入队列时对象的状态是什么?
this.s = "foo";
WeakReference<String> wr = new WeakReference<String>(this.s);
wr.enqueue();
我发现的所有文档都讨论了垃圾收集器排队对象,而不是手动执行时会发生什么。
这有什么意义吗?对象被入队的意义是什么,但仍然有可达的引用(强,弱,幻像)?
编辑:额外奖励后续问题:当物体在遥远的未来某个时间变得无法到达时,它是否会再次入队?
答案 0 :(得分:2)
有一篇关于Java中引用类型的好文章: http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html
用几句话说: 你可以这样做:
public class Main {
public static void main(String[] args) throws InterruptedException{
String weakString = "Help me";
ReferenceQueue<String> refQ = new ReferenceQueue<String>();
WeakReference<String> weakRef = new WeakReference<String>(weakString, refQ);
//there is no more "hard reference to the string"
weakString = null;
//there is no object in ReferenceQueue
System.out.println(refQ.poll());
//put the object in the ReferenceQueue
weakRef.enqueue();
while (true) {
//There will be returned "Help me" until the garbage collector will "kill"
//"weak" string. This will be done after some time because there are no
//more strong references to the string. After that will be returned a null
//object.
System.out.println(weakRef.get());
//only one time there will be returned a refenrece to the String object
System.out.println(refQ.poll());
Thread.sleep(1000);
}
}
}
这是专为处理某种缓存而设计的。
通过这种方式,您可以确保长时间内不会在内存中存在未使用的对象。
在调用weakRef.enqueue();
之后,ReferenceQueue可用于执行某种清理。例如,关闭用于处理数据的文件或流。
答案 1 :(得分:2)
强引用仍然存在,因此该对象不符合收集条件。正如JVestry指出的那样,如果使用队列创建弱引用,则wr.enqueue()会按预期返回true。
这样做的一个潜在用途是让你的处理程序能够对一个对象进行操作,该对象受到其挂起的垃圾收集或其他一些系统状态的改变,你想要采取相同的操作,就像收集对象一样,例如也许你对保存系统资源的内容保持软引用,这样系统可以处理内存不足的情况,而如果你正常完成,你仍然可以自己管理关闭资源。
关于第二个问题,引用只排队一次,无论你是使用enqueue()还是gc作为集合的一部分。
编辑重要的是要记住,参考队列之间的关系是参考,在这种情况下是wr,而不是参考,在这种情况下是s。您可以对同一个对象进行多次弱引用,并实现多个排队(排序),每个弱引用一个。但是,它是队列中的弱引用,而不是引用,尽管它应该仍然可以从弱引用中获得。有关详细信息,请参阅“通知”部分中java.lang.ref上的javadoc。
答案 2 :(得分:1)
在您的情况下,wr.enqueue()将返回false,因为您在创建WeakReference时未指定队列。如果在创建WeakReference时提供ReferenceQueue,则wr.enqueue()将返回true。
手动排列弱引用没有意义。这就像写下弱引用已经被垃圾收集而没有:'s'仍然是对“foo”的强烈引用。
答案 3 :(得分:-1)
有什么情况会有意义吗?
ReferenceQueues有时用于资源管理,在这种情况下调用enqueue()自己在GC运行之前释放资源是有意义的,因为一些资源相当有限(这可以在dispose()方法中完成弱的参考本身作为安全)。
添加:如果清理需要时间,这可能很有用,因为参考队列可以在自己的线程中读取,它不会挂起你的主线程。
对象入队是什么意思,但仍然有可达参考(强,弱,幻影)?
文档声明在对象引用设置为null后调用它,因此enqueue()不能直接影响对象状态当前文档声明enqueue调用未被使用gc,它意味着在gc执行之前对Reference进行排队。引用的对象不会受此调用的影响,但是读取引用队列的清理代码可以处理该对象使用的资源。
<强>编辑:强> 现在检查了1.6文档,因此使用enqueue纠正了关于gc的错误(旧的文档没有指出这一点,但是限制gc对用户代码的暴露是有意义的)