< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 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         }
 131 
 132         ReferenceHandler(ThreadGroup g, String name) {
 133             super(g, null, name, 0, false);
 134         }
 135 
 136         public void run() {
 137             while (true) {
 138                 processPendingReferences();
 139             }
 140         }
 141     }
 142 
 143     /* Atomically get and clear (set to null) the VM's pending list.







 144      */
 145     private static native Reference<Object> getAndClearReferencePendingList();
 146 
 147     /* Test whether the VM's pending list contains any entries.

 148      */
 149     private static native boolean hasReferencePendingList();
 150 
 151     /* Wait until the VM's pending list may be non-null.

 152      */
 153     private static native void waitForReferencePendingList();
 154 
 155     private static final Object processPendingLock = new Object();
 156     private static boolean processPendingActive = false;
 157 
 158     private static void processPendingReferences() {
 159         // Only the singleton reference processing thread calls
 160         // waitForReferencePendingList() and getAndClearReferencePendingList().
 161         // These are separate operations to avoid a race with other threads
 162         // that are calling waitForReferenceProcessing().
 163         waitForReferencePendingList();
 164         Reference<Object> pendingList;
 165         synchronized (processPendingLock) {
 166             pendingList = getAndClearReferencePendingList();
 167             processPendingActive = true;
 168         }
 169         while (pendingList != null) {
 170             Reference<Object> ref = pendingList;
 171             pendingList = ref.discovered;


 244      *
 245      * @return   The object to which this reference refers, or
 246      *           <code>null</code> if this reference object has been cleared
 247      */
 248     @HotSpotIntrinsicCandidate
 249     public T get() {
 250         return this.referent;
 251     }
 252 
 253     /**
 254      * Clears this reference object.  Invoking this method will not cause this
 255      * object to be enqueued.
 256      *
 257      * <p> This method is invoked only by Java code; when the garbage collector
 258      * clears references it does so directly, without invoking this method.
 259      */
 260     public void clear() {
 261         this.referent = null;
 262     }
 263 
 264 
 265     /* -- Queue operations -- */
 266 
 267     /**
 268      * Tells whether or not this reference object has been enqueued, either by
 269      * the program or by the garbage collector.  If this reference object was
 270      * not registered with a queue when it was created, then this method will
 271      * always return <code>false</code>.
 272      *
 273      * @return   <code>true</code> if and only if this reference object has
 274      *           been enqueued
 275      */
 276     public boolean isEnqueued() {
 277         return (this.queue == ReferenceQueue.ENQUEUED);
 278     }
 279 
 280     /**
 281      * Adds this reference object to the queue with which it is registered,
 282      * if any.
 283      *
 284      * <p> This method is invoked only by Java code; when the garbage collector
 285      * enqueues references it does so directly, without invoking this method.
 286      *
 287      * @return   <code>true</code> if this reference object was successfully
 288      *           enqueued; <code>false</code> if it was already enqueued or if
 289      *           it was not registered with a queue when it was created
 290      */
 291     public boolean enqueue() {


 292         return this.queue.enqueue(this);
 293     }
 294 
 295 
 296     /* -- Constructors -- */
 297 
 298     Reference(T referent) {
 299         this(referent, null);
 300     }
 301 
 302     Reference(T referent, ReferenceQueue<? super T> queue) {
 303         this.referent = referent;
 304         this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
 305     }
 306 
 307     /**
 308      * Ensures that the object referenced by the given reference remains
 309      * <a href="package-summary.html#reachability"><em>strongly reachable</em></a>,
 310      * regardless of any prior actions of the program that might otherwise cause
 311      * the object to become unreachable; thus, the referenced object is not
 312      * reclaimable by garbage collection at least until after the invocation of
 313      * this method.  Invocation of this method does not itself initiate garbage
 314      * collection or finalization.
 315      *


 402      * <p> Method {@code reachabilityFence} is not required in constructions
 403      * that themselves ensure reachability.  For example, because objects that
 404      * are locked cannot, in general, be reclaimed, it would suffice if all
 405      * accesses of the object, in all methods of class {@code Resource}
 406      * (including {@code finalize}) were enclosed in {@code synchronized (this)}
 407      * blocks.  (Further, such blocks must not include infinite loops, or
 408      * themselves be unreachable, which fall into the corner case exceptions to
 409      * the "in general" disclaimer.)  However, method {@code reachabilityFence}
 410      * remains a better option in cases where this approach is not as efficient,
 411      * desirable, or possible; for example because it would encounter deadlock.
 412      *
 413      * @param ref the reference. If {@code null}, this method has no effect.
 414      * @since 9
 415      */
 416     @DontInline
 417     public static void reachabilityFence(Object ref) {
 418         // Does nothing, because this method is annotated with @DontInline
 419         // HotSpot needs to retain the ref and not GC it before a call to this
 420         // method
 421     }
 422 
 423 }
   1 /*
   2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


 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         }
 131 
 132         ReferenceHandler(ThreadGroup g, String name) {
 133             super(g, null, name, 0, false);
 134         }
 135 
 136         public void run() {
 137             while (true) {
 138                 processPendingReferences();
 139             }
 140         }
 141     }
 142 
 143     /*
 144      * system property to disable clearing before enqueuing.
 145      */
 146     private static final boolean disableClearBeforeEnqueue
 147         = Boolean.getBoolean("jdk.ref.disableClearBeforeEnqueue");
 148 
 149     /*
 150      * Atomically get and clear (set to null) the VM's pending list.
 151      */
 152     private static native Reference<Object> getAndClearReferencePendingList();
 153 
 154     /*
 155      * Test whether the VM's pending list contains any entries.
 156      */
 157     private static native boolean hasReferencePendingList();
 158 
 159     /*
 160      * Wait until the VM's pending list may be non-null.
 161      */
 162     private static native void waitForReferencePendingList();
 163 
 164     private static final Object processPendingLock = new Object();
 165     private static boolean processPendingActive = false;
 166 
 167     private static void processPendingReferences() {
 168         // Only the singleton reference processing thread calls
 169         // waitForReferencePendingList() and getAndClearReferencePendingList().
 170         // These are separate operations to avoid a race with other threads
 171         // that are calling waitForReferenceProcessing().
 172         waitForReferencePendingList();
 173         Reference<Object> pendingList;
 174         synchronized (processPendingLock) {
 175             pendingList = getAndClearReferencePendingList();
 176             processPendingActive = true;
 177         }
 178         while (pendingList != null) {
 179             Reference<Object> ref = pendingList;
 180             pendingList = ref.discovered;


 253      *
 254      * @return   The object to which this reference refers, or
 255      *           <code>null</code> if this reference object has been cleared
 256      */
 257     @HotSpotIntrinsicCandidate
 258     public T get() {
 259         return this.referent;
 260     }
 261 
 262     /**
 263      * Clears this reference object.  Invoking this method will not cause this
 264      * object to be enqueued.
 265      *
 266      * <p> This method is invoked only by Java code; when the garbage collector
 267      * clears references it does so directly, without invoking this method.
 268      */
 269     public void clear() {
 270         this.referent = null;
 271     }
 272 

 273     /* -- Queue operations -- */
 274 
 275     /**
 276      * Tells whether or not this reference object has been enqueued, either by
 277      * the program or by the garbage collector.  If this reference object was
 278      * not registered with a queue when it was created, then this method will
 279      * always return <code>false</code>.
 280      *
 281      * @return   <code>true</code> if and only if this reference object has
 282      *           been enqueued
 283      */
 284     public boolean isEnqueued() {
 285         return (this.queue == ReferenceQueue.ENQUEUED);
 286     }
 287 
 288     /**
 289      * Clears this reference object and adds it to the queue with which
 290      * it is registered, if any.
 291      *
 292      * <p> This method is invoked only by Java code; when the garbage collector
 293      * enqueues references it does so directly, without invoking this method.
 294      *
 295      * @return   <code>true</code> if this reference object was successfully
 296      *           enqueued; <code>false</code> if it was already enqueued or if
 297      *           it was not registered with a queue when it was created
 298      */
 299     public boolean enqueue() {
 300         if (!disableClearBeforeEnqueue)
 301             this.referent = null;
 302         return this.queue.enqueue(this);
 303     }
 304 

 305     /* -- Constructors -- */
 306 
 307     Reference(T referent) {
 308         this(referent, null);
 309     }
 310 
 311     Reference(T referent, ReferenceQueue<? super T> queue) {
 312         this.referent = referent;
 313         this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
 314     }
 315 
 316     /**
 317      * Ensures that the object referenced by the given reference remains
 318      * <a href="package-summary.html#reachability"><em>strongly reachable</em></a>,
 319      * regardless of any prior actions of the program that might otherwise cause
 320      * the object to become unreachable; thus, the referenced object is not
 321      * reclaimable by garbage collection at least until after the invocation of
 322      * this method.  Invocation of this method does not itself initiate garbage
 323      * collection or finalization.
 324      *


 411      * <p> Method {@code reachabilityFence} is not required in constructions
 412      * that themselves ensure reachability.  For example, because objects that
 413      * are locked cannot, in general, be reclaimed, it would suffice if all
 414      * accesses of the object, in all methods of class {@code Resource}
 415      * (including {@code finalize}) were enclosed in {@code synchronized (this)}
 416      * blocks.  (Further, such blocks must not include infinite loops, or
 417      * themselves be unreachable, which fall into the corner case exceptions to
 418      * the "in general" disclaimer.)  However, method {@code reachabilityFence}
 419      * remains a better option in cases where this approach is not as efficient,
 420      * desirable, or possible; for example because it would encounter deadlock.
 421      *
 422      * @param ref the reference. If {@code null}, this method has no effect.
 423      * @since 9
 424      */
 425     @DontInline
 426     public static void reachabilityFence(Object ref) {
 427         // Does nothing, because this method is annotated with @DontInline
 428         // HotSpot needs to retain the ref and not GC it before a call to this
 429         // method
 430     }

 431 }
< prev index next >