Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4305140

(ref) Add ReferentNContextsQueue

    XMLWordPrintable

    Details

    • Type: Enhancement
    • Status: Open
    • Priority: P5
    • Resolution: Unresolved
    • Affects Version/s: 1.2.2
    • Fix Version/s: None
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Understanding:
      Fix Understood
    • CPU:
      generic, x86
    • OS:
      generic, windows_98

      Description

      orig synopsis: "java.lang.ref.ReferentQueue Feature Request"
      second version: "Feature Request: java.lang.ref.ReferentNContextsQueue"



      Name: krT82822 Date: 01/17/2000


      1.2.2 its a Feature Request


         Note: Recently I have sent you a feature request and got from you:
         "Your report has been assigned an internal review ID of: 100019"
          That feature request is a solution to only part of the problem and serves
         as an introductory here, in Chapter 1.
          I have developed that introductory idea a bit further and got to
         what I present here, in chapter 2, which solves the whole problem.




         Feature Request: java.lang.ref.ReferentNContextsQueue
         --------------------------------------------

         The Situation today:
         -------------------
         I find java.lang.ref missing the ability to process
         ignorant object referent, when they become not strongly
         reachable.

         Say you want to softly refer to some object obj,
         which doesn't care about you, and don't have a
         finalize that take your cause under consideration.

         When that obj dies you don't have the ability to
         inspect it, so you can not do statistics calculations
         about it and you can't serialize it, in case you wanted
         to etc.
                        
         Beside that, even if your object is aware of you and does
         take your cause under consideration in its finalize(),
         there is still that time between the moment it has become
         not-reachable and the time it would be finalized and maybe
         put on a queue to wait for its inspection. In all of which it
         is unreachable by the Reference, and the usual way the program
         works. That time cause major synchronization problems.

         The following will show how the problem may be solved:



         Chapter 1 - Introduction to the concept of ReferentQueue
         =======================================================

         My Proposal:

         I would suggest introducing a ReferentQueue which
         would hold obj before it dies.
        
         For that cause I also introduce an additional state of
         a Reference: clearable. A Reference may be cleared only
         if it is in the clearable state.

         Entering the clearable state:
         ----------------------------
         ( First the Reference is not-clearable. )
         When a Reference referent become not strongly reachable the
         GC will add the referent to the ReferentQueue, where it
         is strongly reachable, and change the Reference state to clearable.

         Exiting the clearable state:
         ----------------------------
         ( First the Reference is clearable. )
         If the referent will be accessed using the References
         get() method its state will change to not-clearable again.

          That is because Reference is used to implement some kind
         of a cache reference to objects. Having the cache accessed
         means the object is in regular use again. Therefor the
         Reference must stay.

         Actually Clearing
         -------------
         If a Reference is clearable and its referent not strongly
         reachable it may be cleared.

         If the get() method has not been invoked and
         the referent becomes not strongly reachable again(*), then
         the GC will detect References referent to be not strongly reachable
         and clearable. Under these conditions References will be cleared.

         ( (*) ReferentQueue lost its reference of the referent by
         dequeueing and the referent inspection is done and
         references to it are lost. )

         
                        

         Analysis
         ========
         The Reference class is usually used for referring to
         objects without preventing them from being
         reclaimed by the GC.

         My proposal does prevent it from being reclaimed
         until it has been processed. But it does give the
         programmer an opportunity to inspect ignorant
         objects, when the object is registered with a
         ReferentQueue.

         The algorithm operate by welcoming two
         possibilities for the referent obj:

         A. obj becomes not strongly reachable. It is
         enqueued to its ReferentQueue and all References
         to obj become clearable. The program uses the
         ReferentQueue and obj, and eventually obj becomes
         not strongly reachable. Now all References to obj
         are beeing cleared and may be put on a ReferenceQueue.
         At this time obj is lost by the Reference mechanism.

         B. obj becomes not strongly reachable. It is
         enqueued to its ReferentQueue and all References
         to it become clearable. Now something in the program
         access obj through a Reference, making it not-
         clearable and so prevent the possibility of it being
         cleared. Now for the References to obj to become
         clearable again, it will have to become not strongly
         reachable again.

         Note the difference between getting obj from a
         Reference which means that you use it in the usual
         way of the program and accessing it from the
         ReferentQueue which means inspection of obj before
         it will be cleared.



         Epilog
         ======

         I don't know the implementation of the GC, but it seems to
         me it all can be done by adding one boolean for the clearable
         state checking in the Reference class and one queue for the
         referents.

         Beside that, the usual mechanism of the GC seems to be doing all
         the work: detecting strongly referenced object, and other ranks
         reachable object, which is enough for knowing which object to add
         to the ReferentQueue.

         The current SoftReference and WeakReference classes may be used
         again with an additional ability to register with a ReferentQueue
         the constructor will look like:

         public SoftReference( Object referent,
                               ReferenceQueue referenceQueue,
                               ReferentQueue referentQueueu );
          
         The ability to tell whether the Reference is clearable
         might be useful as well:

         public boolean is_clearable();

         And the difference between soft and weak will be as always:
         weak are cleared when they can be, soft are cleared when they
         can be and the GC feels like clearing them.
         

         Chapter 2 - Extending the previous idea to deal
         ========= with the totally ignorant object.
                     ================================


         Totally ignorant objects and context
         ===================================

         The text above describes how to inspect the referent before it
         dies. That kind of inspection is important if one does statistics
         analysis of the objects and needs only the data which is in them.
         
         However, most object has a context to them. For example: A persistent
         object which needs to have an object number ID, so when it dies it could
         be saved under the same number. Or a program that test the time some
         objects live, when they are created it need to have the birth Date so when
         it dies the inspection could calculate the age of the object on death.

         For these and other reasons some referents needs a context, which will
         get with them to the ReferentQueueu. One can now say "well simply put
         the context in the referent object and inspect it in the ReferentQueue".
         But that would be wrong, because a totally ignorant object wasn't written
         to suit your cause. So it doesn't know it is persistence. It doesn't
         know you measure its lifetime. etc.' .

         So there is a need for a Reference class which holds another Object
         which represent the context: { Object context; } one can call this
         class ContextSoftReference, and ContextWeakReference.
         
         Operation
         =========

         As before with the ReferentQueue, now there would be a
      ReferentNContextsQueue
         which will hold tupples of { referent, contexts_set } which is the referent
         and a Set containing all contexts of the referent. These contexts would be
         found at the ContextWeakReferences which refers to the referent.
         lets call the { referent, contexts_set } tupple ReferentNContexts

         The algorithm will operate in the same way as before, with one difference:
         When it has been determined that the referent of the Reference needs to
         be enqueued, the referent will be put in a ReferentNContexts as the referent
         and the context form the ContextWeakReferences will be inserted into the
         contexts_set of ReferentNContexts object. Now after all ContextWeakReference
         referring to that referent has been examined and their contexts added to the
         contexts_set, this ReferentNContexts object will be enqueued to the
         ReferentNContextsQueue.

         Now when the user will want to examine the objects that are near their end,
         the user will just need to dequeue form the ReferentNContextsQueue, get
         the referent and evaluate it with each of the contexts in the contexts
         set.

         I have already given some examples of what context might be, but I think
         there are a lot of other example, because this mechanism is really flexible
         and lets the user define what the context will be. Whether just a Long
         with the birth-date, an object number ID, or even a special context
         class which has an interface for processing the object, in which case many
         classes could be directed to the same queue for processing.

         Epilog
         ======

         This development also looks to me very easy to implement, after all
         if the GC can clear when it finds the referent not-strongly-reachable
         it can also get a context from the Reference and put it in a contexts_set.

         The constructor will look like:
         public ContextWeakReference( Object referent,
                                      ReferenceQueue referenceQueue,
                                      Object context,
                                      ReferentNContextsQueue referentNcontextsQueue);

         The ability to tell whether the Reference is clearable
         might be useful as well:
         public boolean is_clearable();
         
         And beside that the API is like for a usual Reference subclass.

         This new classes can do the job of the ReferentQueue by giving a null
         context. This class is much more useful then Chapter 1's.
         ContextWeakReference and ContextSoftReference should be implemented.
         After that I am not sure if the class that is in Chapter 1 is necessary.
         Though it doesn't hurt to have it as well.
      (Review ID: 100068)
      ======================================================================

        Attachments

          Activity

            People

            Assignee:
            mr Mark Reinhold
            Reporter:
            kryansunw Kevin Ryan (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Imported:
              Indexed: