了解与参考队列相关的Phantom参考与弱参考

时间:2014-10-06 07:31:28

标签: java garbage-collection weak-references soft-references phantom-reference

根据链接https://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html PhantomReferences 只有在从内存中物理删除对象并且 WeakReferences 在最终确定或实际垃圾收集之前入队时才会加入队列发生了。

  

区别在于排队发生的时间。   WeakReferences在它们指向的对象后立即排队   变弱了。这是在最终确定或垃圾之前   收集实际上发生了;理论上,这个对象甚至可以   通过非正统的finalize()方法“复活”,但是   WeakReference将继续死亡。 PhantomReferences仅排队   当物体从内存中物理移除时,get()   方法总是返回null,以防止您能够   “复活”一个几乎死了的物体。

然后根据http://www.ibm.com/developerworks/library/j-refs/,在释放堆对象之前将 PhantomReference 添加到其 ReferenceQueue ,并添加 WeakReferences 在完成或垃圾收集之后到它的ReferenceQueue。

  

与软引用和弱引用不同,PhantomReference被添加到其中   释放堆对象之前的ReferenceQueue。 (记住,全部   必须使用关联的对象创建PhantomReference对象   ReferenceQueue。)这允许在堆之前采取行动   对象被收回。

     

当运行堆对象的finalize()方法并释放其内存时,   WeakReference对象被添加到它的ReferenceQueue(如果存在)。

我很困惑。哪一个是正确的?

基本上我想知道关于Reference Queue的弱引用和幻像引用之间的区别吗?

1 个答案:

答案 0 :(得分:6)

在ReferenceQueue上:

WeakReference和PhantomReference都会在它们的引用对象(引用对象)不可强烈访问后排队,如果它们在创建时注册了非空引用队列。

在为队列传递之前,WeakReference清除(取消)引用字段以使引用完全无法访问。当WeakReference被清除时,应用程序不能再获得()指示对象。这意味着,当稍后WeakReference入队时,get()返回null。 WeakReference可能没有在创建时注册的引用队列。应用程序可以通过get()来检测它的指示对象是否无法访问。有时,当应用程序不想显式管理WeakReferences时,引用队列很方便管理WeakReferences。

在传入队列之前,PhantomReference不会清除引用字段。当它入队时,PhantomReference仍会引用所指对象。只有在引用队列出列后,应用程序才会明确清除引用对象。如果应用程序没有清除它,那么指示物仍然存在,直到它和它的PhantomReference一起被回收。在任何情况下,PhantomReference上的get()总是返回null,即使它没有被清除。因此,应用程序无法通过get()来检测它的指示对象是否无法访问。应用程序只能通过检查PhantomReference是否排队来检测。因此,必须使用已注册的引用队列创建PhantomReference;否则,它就没用了。

结束时:

清除WeakReference后,指示对象变得无法访问。如果指示物具有非默认的终结器,则它将被完成,因此将被复活。如果指示物没有非默认的终结器,则它可以由GC回收。换句话说,在完成之前处理WeakReferences。

如果PhantomReference的指示对象只能通过PhantomReference访问,那么它还没有幻像可达。如果在完成后仍然如此(只能通过PhantomReference访问),则只能进行幻象访问。换句话说,PhantomReferences在完成后处理。只有那些没有通过最终确定而复活的指称物是幻影可达的,因此它们肯定会死亡。但是从那时起PhantomReference将被排队,那些指称对象尚未死亡。它们只有在应用程序稍后清除PhantomReferences时才会变为可回收,或者PhantomReferences自身无法访问(然后PhantomReference及其指示对象一起被回收。)