This discussion is archived
1 2 Previous Next 16 Replies Latest reply: Mar 23, 2010 4:53 AM by 791266 RSS

RFE: Concise, practical documentation on PhantomReference

800406 Newbie
Currently Being Moderated
Hi,

I would love for someone "in the know" to post a concise document about how to use java.lang.ref.PhantomReference. There seem to be a lot of rumors floating around but few actual facts. Ideally someone at Sun should post a formal document on the matter. Some questions I would love to get answered:

1) Do PhantomReferences prevent the referent from getting garbage collected (even though it has been finalized) until they have been clear()ed? If so, why? What is the advantage of delaying GC of the object if you can't refer to it? Even in the case where your object has native resources you would like to clear, I see no need to keep the Java object around in order to clean up the native resources later.

2) How is PhantomReference any better than finalization? Don't bother mechanisms require a minimum of two GC cycles to free any referent object?

3) I've seen two schools on thought on how to use PhantomReferences. One says you should a Map<PhantomReference, StuffToCleanUp> to figure out what to do when a PhantomReference shows up on your ReferenceQueue. The second school of thought is to subclass the PhantomReference and add that information directly into it.

4) I've seen some people advocating keeping a strong reference to the referent in the PhantomReference subclass. Doesn't this prevent the referent from ever becoming "phantom reachable"? Or are strong references coming out of Weak/Soft/PhantomReferences ignored by the garbage-collector?

5) I've seen other people advocating subclassing PhantomReference and pointing to some data that needs to be cleaned up but not the original referent. So for example, you would point to some native data that needs to be cleaned up, not to the referent which was a Java object that used it.

6) Out of all suggestions I think #5 sounds the safest, but it still isn't clear to me why one would use PhantomReferences over WeakReferences with the same cleanup mechanism. I suspect this is because there is a danger that WeakReference referents might be brought back to life by a finalize() method, so you don't want to clean up any resources before you are 100% sure the referent will not be coming back to life. Is that correct?

Thank you,
Gili
  • 1. Re: RFE: Concise, practical documentation on PhantomReference
    800406 Newbie
    Currently Being Moderated
    Forgot one more question:

    7) Go to http://forum.java.sun.com/thread.jspa?forumID=31&threadID=760557 and search for "ConnectionHolder" in this page. Why did the developer think that you need to give users a proxy to the referent as opposed to letting them access it directly? That is, why can't you give users direct access to the real connection and construct your PhantomReference independently of that? Won't the object become phantom-reachable the same way in both cases?
    <br>
    <br>
    I also forgot to mention some reference documentation I've found useful on this topic:

    1) Good theoretical background: http://java.sun.com/developer/technicalArticles/ALT/RefObj/

    2) More practical background: http://weblogs.java.net/blog/enicholas/archive/2006/05/understanding_w.html

    3) The evaluation of this bug seems to imply that strong references owned by Soft/Weak/PhantomReferences are ignored by the GC: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4497818

    4) Talks about PhantomReference subclases containing cleanup information: http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=1&t=014681
  • 2. Re: RFE: Concise, practical documentation on PhantomReference
    EJP Guru
    Currently Being Moderated
    1) Do PhantomReferences prevent the referent from getting garbage collected (even though it has been finalized) until they have been clear()ed?
    That's what it says in the Javadoc.
    If so, why?
    Because that's what PhantomReferences are for ...
    2) How is PhantomReference any better than finalization?
    'More flexible' according to the Javadoc ...
    4) I've seen some people advocating keeping a strong reference to the referent in the PhantomReference subclass. Doesn't this prevent the referent from ever becoming "phantom reachable"?
    Correct.
    Or are strong references coming out of Weak/Soft/PhantomReferences ignored by the garbage-collector?
    Not according to the Javadoc.
    6) Out of all suggestions I think #5 sounds the safest, but it still isn't clear to me why one would use PhantomReferences over WeakReferences with the same cleanup mechanism. I suspect this is because there is a danger that WeakReference referents might be brought back to life by a finalize() method, so you don't want to clean up any resources before you are 100% sure the referent will not be coming back to life. Is that correct?
    I believe so.
  • 3. Re: RFE: Concise, practical documentation on PhantomReference
    800406 Newbie
    Currently Being Moderated
    Thanks ejp!

    I just have a few more open questions :)

    - With respect to #3, does it make a difference which approach is used? Is there an advantage one way or another?
    - With respect to http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4497818 does that mean the Sun Engineer was wrong in his evaluation?
    - With respect to #7, does it matter whether users access the referent directly or you provide them a proxy to it?
    - I understand PhantomReferences are more flexible than finalization, but are the more efficient? Doesn't the GC still require a minimum of two passes before cleaning the referent?

    Thank you,
    Gili

    Edited by: cowwoc on Oct 26, 2007 1:54 PM
  • 4. Re: RFE: Concise, practical documentation on PhantomReference
    843798 Newbie
    Currently Being Moderated
    cowwoc wrote:
    Hi,

    I would love for someone "in the know" to post a concise document about how to use java.lang.ref.PhantomReference. There seem to be a lot of rumors floating around but few actual facts. Ideally someone at Sun should post a formal document on the matter. Some questions I would love to get answered:

    1) Do PhantomReferences prevent the referent from getting garbage collected (even though it has been finalized) until they have been clear()ed? If so, why? What is the advantage of delaying GC of the object if you can't refer to it? Even in the case where your object has native resources you would like to clear, I see no need to keep the Java object around in order to clean up the native resources later.
    Depends on what you mean by "garbage collected". GC is not a single step process. An object can go Soft or weak while having still a phantom reference. If you want to do cleanup before the object is release, then the phantom reference will allow you since it holds until you clear it. but once it goes phantom its not coming back.

    >
    2) How is PhantomReference any better than finalization? Don't bother mechanisms require a minimum of two GC cycles to free any referent object?
    What do you mean? Are you asking about Finalizers? finalizers can interfere with the life cycle of an object. phantoms do not.
    3) I've seen two schools on thought on how to use PhantomReferences. One says you should a Map<PhantomReference, StuffToCleanUp> to figure out what to do when a PhantomReference shows up on your ReferenceQueue. The second school of thought is to subclass the PhantomReference and add that information directly into it.
    Either way works. Sometimes I subclass to attach additional diagnostic information to a reference such as a name or description.
    4) I've seen some people advocating keeping a strong reference to the referent in the PhantomReference subclass. Doesn't this prevent the referent from ever becoming "phantom reachable"? Or are strong references coming out of Weak/Soft/PhantomReferences ignored by the garbage-collector?
    This would keep the referent from ever becoming soft/weak/phantomly reachable unless the reference itself also became soft/weak/phantomly reachable.
    5) I've seen other people advocating subclassing PhantomReference and pointing to some data that needs to be cleaned up but not the original referent. So for example, you would point to some native data that needs to be cleaned up, not to the referent which was a Java object that used it.
    That works.
    6) Out of all suggestions I think #5 sounds the safest, but it still isn't clear to me why one would use PhantomReferences over WeakReferences with the same cleanup mechanism. I suspect this is because there is a danger that WeakReference referents might be brought back to life by a finalize() method, so you don't want to clean up any resources before you are 100% sure the referent will not be coming back to life. Is that correct?
    That is correct. Consider that you are writing a library and can not control directly the life of some references. Perhaps the user of your library wants to do some caching or other use of references on his own. If you use soft references you would interfere with any end users use of weak references. if you use weak references you would interfere with any end users use of phantom references. But one phantom reference will not interfere with the use of another phantom reference if used carefully.
    Thank you,
    Gili
  • 5. Re: RFE: Concise, practical documentation on PhantomReference
    843798 Newbie
    Currently Being Moderated
    cowwoc wrote:
    Forgot one more question:

    7) Go to http://forum.java.sun.com/thread.jspa?forumID=31&threadID=760557 and search for "ConnectionHolder" in this page. Why did the developer think that you need to give users a proxy to the referent as opposed to letting them access it directly? That is, why can't you give users direct access to the real connection and construct your PhantomReference independently of that? Won't the object become phantom-reachable the same way in both cases?
    Because the developer wants to use the connection after the end user has finished with it. So he gives the end user a wrapper that will be reclaimed when the end user is done. But this is not the actual connection since the developer still wants to use it one last time. If this was the actual connection, then it could not be used again since it would be enqueued. And since this is a phantom reference we can not get the referent back. And of course by now you know the pitfalls of actually getting the referent back and using it.

    <br>
    <br>
    I also forgot to mention some reference documentation I've found useful on this topic:
    >
    3) The evaluation of this bug seems to imply that strong references owned by Soft/Weak/PhantomReferences are ignored by the GC: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4497818
    Not really. Its explaining the same thing from #7 above.
  • 6. Re: RFE: Concise, practical documentation on PhantomReference
    800406 Newbie
    Currently Being Moderated
    Thanks for explaining #7! It makes so much more sense now :)
    Depends on what you mean by "garbage collected". GC is not a single step process. An object can go Soft or weak while having still a phantom reference. If you want to do cleanup before the object is release, then the phantom reference will allow you since it holds until you clear it. but once it goes phantom its not coming back.
    That's the thing I don't understand: what is gained by having PhantomReference keep the underlying object alive until clear() is explicitly invoked? Who cares whether the cleanup occurs before or after the underlying object is released? Take the #7 use-case for example, the PhantomReference would get enqueued after ConnectionHolder is released but this would not prevent you from getting a reference to the underlying connection and finishing the cleanup. Did I miss something?
    This would keep the referent from ever becoming soft/weak/phantomly reachable unless the reference itself also became soft/weak/phantomly reachable.
    Okay, what happens in the following scenario?
    new PhantomReference(myObject, myReferenceQueue);
    Seeing as I don't keep a strong reference to the phantom-reference anywhere, doesn't this mean that the reference will get queued even if the phantom-reference contains a strong reference to myObject?

    Thanks,
    Gili
  • 7. Re: RFE: Concise, practical documentation on PhantomReference
    843798 Newbie
    Currently Being Moderated
    cowwoc wrote:
    Thanks for explaining #7! It makes so much more sense now :)
    Depends on what you mean by "garbage collected". GC is not a single step process. An object can go Soft or weak while having still a phantom reference. If you want to do cleanup before the object is release, then the phantom reference will allow you since it holds until you clear it. but once it goes phantom its not coming back.
    That's the thing I don't understand: what is gained by having PhantomReference keep the underlying object alive until clear() is explicitly invoked? Who cares whether the cleanup occurs before or after the underlying object is released? Take the #7 use-case for example, the PhantomReference would get enqueued after ConnectionHolder is released but this would not prevent you from getting a reference to the underlying connection and finishing the cleanup. Did I miss something?
    I think you need too look at it another way. The only reason Weak and Soft References' referrents are automatically cleared is because their referents are accessible. If they were not cleared, then the end user could turn a Weak/Soft reference back into a strong reference which would be wrong. Reference strength only changes in one direction. Since the Phantom Reference's referent is not accessible, then there is no reason for the GC to automatically clear it.

    So while the Weak/Soft References give the user more choice by making the referent available, the Phantom Reference gives the user more choice by keeping the referent until the user clears it. Else soft/weak would also require a reference queue and a map to use.

    This would keep the referent from ever becoming soft/weak/phantomly reachable unless the reference itself also became soft/weak/phantomly reachable.
    Okay, what happens in the following scenario?
    new PhantomReference(myObject, myReferenceQueue);
    Seeing as I don't keep a strong reference to the phantom-reference anywhere, doesn't this mean that the reference will get queued even if the phantom-reference contains a strong reference to myObject?
    Your out-thinking yourself. If you do not keep a strong reference to the PhantomReference, then it will be GCed and nothing else matters.
  • 8. Re: RFE: Concise, practical documentation on PhantomReference
    800406 Newbie
    Currently Being Moderated
    _dnoyeB wrote:
    I think you need too look at it another way. The only reason Weak and Soft References' referrents are automatically cleared is because their referents are accessible. If they were not cleared, then the end user could turn a Weak/Soft reference back into a strong reference which would be wrong. Reference strength only changes in one direction. Since the Phantom Reference's referent is not accessible, then there is no reason for the GC to automatically clear it.
    I understand your argument for Weak/Soft references but I still think it is more efficient for the GC to automatically clear PhantomReferences (even if it doesn't have to) and there is no good reason why it does not. Does anyone know why this is the case?
    Seeing as I don't keep a strong reference to the phantom-reference anywhere, doesn't this mean that the reference will get queued even if the phantom-reference contains a strong reference to myObject?
    Your out-thinking yourself. If you do not keep a strong reference to the PhantomReference, then it will be GCed and nothing else matters.
    I'm not sure I understand. Are you saying that the PhantomReference will get GC without getting enqueued in the ReferenceQueue or are you saying it will get enqueued right away?

    Thanks,
    Gili
  • 9. Re: RFE: Concise, practical documentation on PhantomReference
    843798 Newbie
    Currently Being Moderated
    cowwoc wrote:
    _dnoyeB wrote:
    I think you need too look at it another way. The only reason Weak and Soft References' referrents are automatically cleared is because their referents are accessible. If they were not cleared, then the end user could turn a Weak/Soft reference back into a strong reference which would be wrong. Reference strength only changes in one direction. Since the Phantom Reference's referent is not accessible, then there is no reason for the GC to automatically clear it.
    I understand your argument for Weak/Soft references but I still think it is more efficient for the GC to automatically clear PhantomReferences (even if it doesn't have to) and there is no good reason why it does not. Does anyone know why this is the case?
    Just because you can't think of a use today does not mean you should eliminate the possibility of there ever being one. Some don't see a use for phantom references, but others will find them. There is no efficiency gained by having the GC clear the referent. Its only done when its absolutely required. In this case it is not.

    Seeing as I don't keep a strong reference to the phantom-reference anywhere, doesn't this mean that the reference will get queued even if the phantom-reference contains a strong reference to myObject?
    Your out-thinking yourself. If you do not keep a strong reference to the PhantomReference, then it will be GCed and nothing else matters.
    I'm not sure I understand. Are you saying that the PhantomReference will get GC without getting enqueued in the ReferenceQueue or are you saying it will get enqueued right away?
    The enqueueing of the Phantom reference depends on the behavior of the referent. But the phantom reference also has to be alive to be acted upon. If the phantom reference is GC before its referent, then no, it will not get enqueued.

    Note that the queue is added to the reference and not vice versa. The reference can keep the queue alive, but I don't think the queue will keep the reference alive.

    So yes the PhantonReference may get GC without being enqueued. Its not guaranteed, so it would be bad practice to count on it.
  • 10. Re: RFE: Concise, practical documentation on PhantomReference
    800406 Newbie
    Currently Being Moderated
    Bob Lee pointed me to an excellent discussion about PhantomReference: http://discuss.develop.com/archives/wa.exe?A2=ind0101&L=advanced-java&P=11624

    It turns out that the reason PhantomReferences do not automatically clear the referent is due to a <b>software patent</b>! :(

    A final question comes to mind: is there a way to ensure that OutOfMemoryError is not thrown so long as there are Soft/Weak/PhantomReferences that may be garbage collected? I am guessing this is technically possible for Soft/Weak but not PhantomReferences because the latter have to be cleared manually.

    Gili
  • 11. Re: RFE: Concise, practical documentation on PhantomReference
    843798 Newbie
    Currently Being Moderated
    A final question comes to mind: is there a way to ensure that OutOfMemoryError is not thrown so long as there are Soft/Weak/PhantomReferences that may be garbage collected? I am guessing this is technically possible for Soft/Weak but not PhantomReferences because the latter have to be cleared manually.

    Gili
    Soft is the only one guaranteed to be cleared before OOM. However, weak references appear to be enqueued more agressively than soft references, and phantom more agressively than weak.
  • 12. Re: RFE: Concise, practical documentation on PhantomReference
    800406 Newbie
    Currently Being Moderated
    FYI: The discussion about PhantomReference has been moved to: http://peach.ease.lsoft.com/scripts/wa.exe?A2=ind0101&L=ADVANCED-JAVA&P=R5122&1=ADVANCED-JAVA&J=on&z=4
  • 13. Re: RFE: Concise, practical documentation on PhantomReference
    EJP Guru
    Currently Being Moderated
    Moved by whom? I'm still here, so is _dnoyeB                                                                                                                                                                                                                   
  • 14. Re: RFE: Concise, practical documentation on PhantomReference
    800406 Newbie
    Currently Being Moderated
    A few posts ago I wrote:

    >
    Bob Lee pointed me to an excellent discussion about PhantomReference: http://discuss.develop.com/archives/wa.exe?A2=ind0101&L=advanced-java&P=11624
    >

    That link is now broken and has been replaced by the new link I just posted.
1 2 Previous Next