< prev index next >

src/java.base/share/classes/java/lang/ref/Reference.java

Print this page
rev 50093 : [mq]: pp2_work


  26 package java.lang.ref;
  27 
  28 import jdk.internal.vm.annotation.ForceInline;
  29 import jdk.internal.HotSpotIntrinsicCandidate;
  30 import jdk.internal.misc.JavaLangRefAccess;
  31 import jdk.internal.misc.SharedSecrets;
  32 import jdk.internal.ref.Cleaner;
  33 
  34 /**
  35  * Abstract base class for reference objects.  This class defines the
  36  * operations common to all reference objects.  Because reference objects are
  37  * implemented in close cooperation with the garbage collector, this class may
  38  * not be subclassed directly.
  39  *
  40  * @author   Mark Reinhold
  41  * @since    1.2
  42  */
  43 
  44 public abstract class Reference<T> {
  45 
  46     /* A Reference instance is in one of four possible internal states:


  47      *
  48      *     Active: Subject to special treatment by the garbage collector.  Some
  49      *     time after the collector detects that the reachability of the
  50      *     referent has changed to the appropriate state, it changes the
  51      *     instance's state to either Pending or Inactive, depending upon
  52      *     whether or not the instance was registered with a queue when it was
  53      *     created.  In the former case it also adds the instance to the
  54      *     pending-Reference list.  Newly-created instances are Active.
  55      *
  56      *     Pending: An element of the pending-Reference list, waiting to be
  57      *     enqueued by the Reference-handler thread.  Unregistered instances
  58      *     are never in this state.
  59      *
  60      *     Enqueued: An element of the queue with which the instance was
  61      *     registered when it was created.  When an instance is removed from
  62      *     its ReferenceQueue, it is made Inactive.  Unregistered instances are
  63      *     never in this state.
  64      *
  65      *     Inactive: Nothing more to do.  Once an instance becomes Inactive its
  66      *     state will never change again.
  67      *
  68      * The state is encoded in the queue and next fields as follows:
  69      *
  70      *     Active: queue = ReferenceQueue with which instance is registered, or
  71      *     ReferenceQueue.NULL if it was not registered with a queue; next =
  72      *     null.
  73      *
  74      *     Pending: queue = ReferenceQueue with which instance is registered;
  75      *     next = this
  76      *
  77      *     Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
  78      *     in queue, or this if at end of list.
  79      *
  80      *     Inactive: queue = ReferenceQueue.NULL; next = this.
  81      *
  82      * With this scheme the collector need only examine the next field in order
  83      * to determine whether a Reference instance requires special treatment: If
  84      * the next field is null then the instance is active; if it is non-null,
  85      * then the collector should treat the instance normally.
  86      *
  87      * To ensure that a concurrent collector can discover active Reference
  88      * objects without interfering with application threads that may apply
  89      * the enqueue() method to those objects, collectors should link
  90      * discovered objects through the discovered field. The discovered
  91      * field is also used for linking Reference objects in the pending list.




































  92      */
  93 
  94     private T referent;         /* Treated specially by GC */
  95 
  96     volatile ReferenceQueue<? super T> queue;
  97 
  98     /* When active:   NULL
  99      *     pending:   this
 100      *    Enqueued:   next reference in queue (or this if last)
 101      *    Inactive:   this


 102      */
 103     @SuppressWarnings("rawtypes")
 104     volatile Reference next;
 105 
 106     /* When active:   next element in a discovered reference list maintained by GC (or this if last)
 107      *     pending:   next element in the pending list (or null if last)
 108      *   otherwise:   NULL








 109      */
 110     private transient Reference<T> discovered;  /* used by VM */
 111 
 112 
 113     /* High-priority thread to enqueue pending References
 114      */
 115     private static class ReferenceHandler extends Thread {
 116 
 117         private static void ensureClassInitialized(Class<?> clazz) {
 118             try {
 119                 Class.forName(clazz.getName(), true, clazz.getClassLoader());
 120             } catch (ClassNotFoundException e) {
 121                 throw (Error) new NoClassDefFoundError(e.getMessage()).initCause(e);
 122             }
 123         }
 124 
 125         static {
 126             // pre-load and initialize Cleaner class so that we don't
 127             // get into trouble later in the run loop if there's
 128             // memory shortage while loading/initializing it lazily.
 129             ensureClassInitialized(Cleaner.class);
 130         }




  26 package java.lang.ref;
  27 
  28 import jdk.internal.vm.annotation.ForceInline;
  29 import jdk.internal.HotSpotIntrinsicCandidate;
  30 import jdk.internal.misc.JavaLangRefAccess;
  31 import jdk.internal.misc.SharedSecrets;
  32 import jdk.internal.ref.Cleaner;
  33 
  34 /**
  35  * Abstract base class for reference objects.  This class defines the
  36  * operations common to all reference objects.  Because reference objects are
  37  * implemented in close cooperation with the garbage collector, this class may
  38  * not be subclassed directly.
  39  *
  40  * @author   Mark Reinhold
  41  * @since    1.2
  42  */
  43 
  44 public abstract class Reference<T> {
  45 
  46     /* The state of a Reference object is characterized by two attributes.  It
  47      * may be either "active", "pending", or "inactive".  It may also be
  48      * either "registered", "enqueued", "dequeued", or "unregistered".
  49      *
  50      * Active: Subject to special treatment by the garbage collector.  Some
  51      * time after the collector detects that the reachability of the referent
  52      * has changed to the appropriate state, the collector "notifies" the
  53      * reference, changing the state to either "pending" or "inactive".
  54      * referent != null; discovered = null, or in GC discovered list.


  55      *
  56      * Pending: An element of the pending-Reference list, waiting to be
  57      * processed by the Reference-handler thread.  The pending-Reference list
  58      * is linked through the discovered fields of references in the list.
  59      * referent = null; discovered = next element in pending-Reference list.
  60      *
  61      * Inactive: Neither Active nor Pending.
  62      * referent = null.
  63      *
  64      * Registered: Associated with a queue when created, and not yet added to
  65      * the queue.
  66      * queue = the associated queue.
  67      *
  68      * Enqueued: Added to the associated queue, and not yet removed.
  69      * queue = ReferenceQueue.ENQUEUE; next = next entry in list, or this to
  70      * indicate end of list.
  71      *
  72      * Dequeued: Added to the associated queue and then removed.
  73      * queue = ReferenceQueue.NULL; next = this.
  74      *
  75      * Unregistered: Not associated with a queue when created.
  76      * queue = ReferenceQueue.NULL.
  77      *
  78      * The collector only needs to examine the referent field and the
  79      * discovered field to determine whether a normal Reference object needs
  80      * special treatment.  If the referent is non-null and not known to be
  81      * live, then it may need to be discovered for possible later
  82      * notification.  But if the discovered field is non-null, then either (1)
  83      * it has already been discovered, or (2) it is in the pending list.
  84      *
  85      * FinalReference differs from other references, because a FinalReference
  86      * is not cleared when notified.  The referent being null or not cannot be
  87      * used to distinguish between the active state and pending or inactive
  88      * states.  However, FinalReferences do not support enqueue().  Instead,
  89      * the next field of a FinalReference object is set to the object when it
  90      * is added to the pending list, and the use of this as the value of next
  91      * in the enqueued and dequeued states maintains the non-active state.  An
  92      * additional check that the next field is null is required to determine
  93      * that a FinalReference object is active.
  94      *
  95      * Initial states:
  96      *   active/registered
  97      *   active/unregistered [1]
  98      *
  99      * Transitions:
 100      *   active/registered    -> pending/registered    - GC
 101      *                        -> inactive/registered   - clear
 102      *                        -> inactive/enqueued     - enqueue [2]
 103      *   pending/registered   -> pending/enqueued      - enqueue [2]
 104      *                        -> inactive/enqueued     - pending list processing
 105      *   pending/enqueued     -> inactive/enqueued     - pending list processing
 106      *                        -> pending/dequeued      - poll/remove
 107      *   pending/dequeued     -> inactive/dequeued     - pending list processing
 108      *   inactive/registered  -> inactive/enqueued     - enqueue [2]
 109      *   inactive/enqueued    -> inactive/dequeued     - poll/remove
 110      *
 111      *   active/unregistered  -> pending/unregistered  - GC
 112      *                        -> inactive/unregistered - GC, clear, enqueue
 113      *   pending/unregistered -> inactive/unregistered - pending list processing
 114      *
 115      * Terminal states:
 116      *   inactive/dequeued
 117      *   inactive/unregistered
 118      *
 119      * Unreachable states (because enqueue also clears):
 120      *   active/enqeued
 121      *   active/dequeued
 122      *
 123      * [1] Unregistered is not permitted for FinalReferences.
 124      *
 125      * [2] These transitions are not possible for FinalReferences, making
 126      * pending/enqueued and pending/dequeued unreachable, and
 127      * inactive/registered terminal.
 128      */
 129 
 130     private T referent;         /* Treated specially by GC */
 131 
 132     volatile ReferenceQueue<? super T> queue;
 133 
 134     /* The link in a ReferenceQueue's list of Reference objects.
 135      *
 136      * When registered: null
 137      *        enqueued: next element in queue (or this if last)
 138      *        dequeued: this (marking FinalReferences as inactive)
 139      *    unregistered: null
 140      */
 141     @SuppressWarnings("rawtypes")
 142     volatile Reference next;
 143 
 144     /* Used by the garbage collector to accumulate Reference objects that need
 145      * to be revisited in order to decide whether they should be notified.
 146      * Also used as the link in the pending-Reference list.  The discovered
 147      * field and the next field are distinct to allow the enqueue() method to
 148      * be applied to a Reference object while it is either in the
 149      * pending-Reference list or in the garbage collector's discovered set.
 150      *
 151      * When active: null or next element in a discovered reference list
 152      *              maintained by the GC (or this if last)
 153      *     pending: next element in the pending-Reference list (null if last)
 154      *    inactive: null
 155      */
 156     private transient Reference<T> discovered;
 157 
 158 
 159     /* High-priority thread to enqueue pending References
 160      */
 161     private static class ReferenceHandler extends Thread {
 162 
 163         private static void ensureClassInitialized(Class<?> clazz) {
 164             try {
 165                 Class.forName(clazz.getName(), true, clazz.getClassLoader());
 166             } catch (ClassNotFoundException e) {
 167                 throw (Error) new NoClassDefFoundError(e.getMessage()).initCause(e);
 168             }
 169         }
 170 
 171         static {
 172             // pre-load and initialize Cleaner class so that we don't
 173             // get into trouble later in the run loop if there's
 174             // memory shortage while loading/initializing it lazily.
 175             ensureClassInitialized(Cleaner.class);
 176         }


< prev index next >