Reference.java revision 13484:827ce3d74163
1/*
2 * Copyright (c) 1997, 2015, 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
23 * questions.
24 */
25
26package java.lang.ref;
27
28import jdk.internal.vm.annotation.DontInline;
29import sun.misc.Cleaner;
30import jdk.internal.HotSpotIntrinsicCandidate;
31import jdk.internal.misc.JavaLangRefAccess;
32import jdk.internal.misc.SharedSecrets;
33import sun.misc.ManagedLocalsThread;
34
35/**
36 * Abstract base class for reference objects.  This class defines the
37 * operations common to all reference objects.  Because reference objects are
38 * implemented in close cooperation with the garbage collector, this class may
39 * not be subclassed directly.
40 *
41 * @author   Mark Reinhold
42 * @since    1.2
43 */
44
45public abstract class Reference<T> {
46
47    /* A Reference instance is in one of four possible internal states:
48     *
49     *     Active: Subject to special treatment by the garbage collector.  Some
50     *     time after the collector detects that the reachability of the
51     *     referent has changed to the appropriate state, it changes the
52     *     instance's state to either Pending or Inactive, depending upon
53     *     whether or not the instance was registered with a queue when it was
54     *     created.  In the former case it also adds the instance to the
55     *     pending-Reference list.  Newly-created instances are Active.
56     *
57     *     Pending: An element of the pending-Reference list, waiting to be
58     *     enqueued by the Reference-handler thread.  Unregistered instances
59     *     are never in this state.
60     *
61     *     Enqueued: An element of the queue with which the instance was
62     *     registered when it was created.  When an instance is removed from
63     *     its ReferenceQueue, it is made Inactive.  Unregistered instances are
64     *     never in this state.
65     *
66     *     Inactive: Nothing more to do.  Once an instance becomes Inactive its
67     *     state will never change again.
68     *
69     * The state is encoded in the queue and next fields as follows:
70     *
71     *     Active: queue = ReferenceQueue with which instance is registered, or
72     *     ReferenceQueue.NULL if it was not registered with a queue; next =
73     *     null.
74     *
75     *     Pending: queue = ReferenceQueue with which instance is registered;
76     *     next = this
77     *
78     *     Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
79     *     in queue, or this if at end of list.
80     *
81     *     Inactive: queue = ReferenceQueue.NULL; next = this.
82     *
83     * With this scheme the collector need only examine the next field in order
84     * to determine whether a Reference instance requires special treatment: If
85     * the next field is null then the instance is active; if it is non-null,
86     * then the collector should treat the instance normally.
87     *
88     * To ensure that a concurrent collector can discover active Reference
89     * objects without interfering with application threads that may apply
90     * the enqueue() method to those objects, collectors should link
91     * discovered objects through the discovered field. The discovered
92     * field is also used for linking Reference objects in the pending list.
93     */
94
95    private T referent;         /* Treated specially by GC */
96
97    volatile ReferenceQueue<? super T> queue;
98
99    /* When active:   NULL
100     *     pending:   this
101     *    Enqueued:   next reference in queue (or this if last)
102     *    Inactive:   this
103     */
104    @SuppressWarnings("rawtypes")
105    volatile Reference next;
106
107    /* When active:   next element in a discovered reference list maintained by GC (or this if last)
108     *     pending:   next element in the pending list (or null if last)
109     *   otherwise:   NULL
110     */
111    private transient Reference<T> discovered;  /* used by VM */
112
113
114    /* Object used to synchronize with the garbage collector.  The collector
115     * must acquire this lock at the beginning of each collection cycle.  It is
116     * therefore critical that any code holding this lock complete as quickly
117     * as possible, allocate no new objects, and avoid calling user code.
118     */
119    private static class Lock { }
120    private static Lock lock = new Lock();
121
122
123    /* List of References waiting to be enqueued.  The collector adds
124     * References to this list, while the Reference-handler thread removes
125     * them.  This list is protected by the above lock object. The
126     * list uses the discovered field to link its elements.
127     */
128    private static Reference<Object> pending = null;
129
130    /* High-priority thread to enqueue pending References
131     */
132    private static class ReferenceHandler extends ManagedLocalsThread {
133
134        private static void ensureClassInitialized(Class<?> clazz) {
135            try {
136                Class.forName(clazz.getName(), true, clazz.getClassLoader());
137            } catch (ClassNotFoundException e) {
138                throw (Error) new NoClassDefFoundError(e.getMessage()).initCause(e);
139            }
140        }
141
142        static {
143            // pre-load and initialize InterruptedException and Cleaner classes
144            // so that we don't get into trouble later in the run loop if there's
145            // memory shortage while loading/initializing them lazily.
146            ensureClassInitialized(InterruptedException.class);
147            ensureClassInitialized(Cleaner.class);
148        }
149
150        ReferenceHandler(ThreadGroup g, String name) {
151            super(g, name);
152        }
153
154        public void run() {
155            while (true) {
156                tryHandlePending(true);
157            }
158        }
159    }
160
161    /**
162     * Try handle pending {@link Reference} if there is one.<p>
163     * Return {@code true} as a hint that there might be another
164     * {@link Reference} pending or {@code false} when there are no more pending
165     * {@link Reference}s at the moment and the program can do some other
166     * useful work instead of looping.
167     *
168     * @param waitForNotify if {@code true} and there was no pending
169     *                      {@link Reference}, wait until notified from VM
170     *                      or interrupted; if {@code false}, return immediately
171     *                      when there is no pending {@link Reference}.
172     * @return {@code true} if there was a {@link Reference} pending and it
173     *         was processed, or we waited for notification and either got it
174     *         or thread was interrupted before being notified;
175     *         {@code false} otherwise.
176     */
177    static boolean tryHandlePending(boolean waitForNotify) {
178        Reference<Object> r;
179        Cleaner c;
180        try {
181            synchronized (lock) {
182                if (pending != null) {
183                    r = pending;
184                    // 'instanceof' might throw OutOfMemoryError sometimes
185                    // so do this before un-linking 'r' from the 'pending' chain...
186                    c = r instanceof Cleaner ? (Cleaner) r : null;
187                    // unlink 'r' from 'pending' chain
188                    pending = r.discovered;
189                    r.discovered = null;
190                } else {
191                    // The waiting on the lock may cause an OutOfMemoryError
192                    // because it may try to allocate exception objects.
193                    if (waitForNotify) {
194                        lock.wait();
195                    }
196                    // retry if waited
197                    return waitForNotify;
198                }
199            }
200        } catch (OutOfMemoryError x) {
201            // Give other threads CPU time so they hopefully drop some live references
202            // and GC reclaims some space.
203            // Also prevent CPU intensive spinning in case 'r instanceof Cleaner' above
204            // persistently throws OOME for some time...
205            Thread.yield();
206            // retry
207            return true;
208        } catch (InterruptedException x) {
209            // retry
210            return true;
211        }
212
213        // Fast path for cleaners
214        if (c != null) {
215            c.clean();
216            return true;
217        }
218
219        ReferenceQueue<? super Object> q = r.queue;
220        if (q != ReferenceQueue.NULL) q.enqueue(r);
221        return true;
222    }
223
224    static {
225        ThreadGroup tg = Thread.currentThread().getThreadGroup();
226        for (ThreadGroup tgn = tg;
227             tgn != null;
228             tg = tgn, tgn = tg.getParent());
229        Thread handler = new ReferenceHandler(tg, "Reference Handler");
230        /* If there were a special system-only priority greater than
231         * MAX_PRIORITY, it would be used here
232         */
233        handler.setPriority(Thread.MAX_PRIORITY);
234        handler.setDaemon(true);
235        handler.start();
236
237        // provide access in SharedSecrets
238        SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {
239            @Override
240            public boolean tryHandlePendingReference() {
241                return tryHandlePending(false);
242            }
243        });
244    }
245
246    /* -- Referent accessor and setters -- */
247
248    /**
249     * Returns this reference object's referent.  If this reference object has
250     * been cleared, either by the program or by the garbage collector, then
251     * this method returns <code>null</code>.
252     *
253     * @return   The object to which this reference refers, or
254     *           <code>null</code> if this reference object has been cleared
255     */
256    @HotSpotIntrinsicCandidate
257    public T get() {
258        return this.referent;
259    }
260
261    /**
262     * Clears this reference object.  Invoking this method will not cause this
263     * object to be enqueued.
264     *
265     * <p> This method is invoked only by Java code; when the garbage collector
266     * clears references it does so directly, without invoking this method.
267     */
268    public void clear() {
269        this.referent = null;
270    }
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     * Adds this reference object to the queue with which it is registered,
290     * 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        return this.queue.enqueue(this);
301    }
302
303
304    /* -- Constructors -- */
305
306    Reference(T referent) {
307        this(referent, null);
308    }
309
310    Reference(T referent, ReferenceQueue<? super T> queue) {
311        this.referent = referent;
312        this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
313    }
314
315    /**
316     * Ensures that the object referenced by the given reference remains
317     * <a href="package-summary.html#reachability"><em>strongly reachable</em></a>,
318     * regardless of any prior actions of the program that might otherwise cause
319     * the object to become unreachable; thus, the referenced object is not
320     * reclaimable by garbage collection at least until after the invocation of
321     * this method.  Invocation of this method does not itself initiate garbage
322     * collection or finalization.
323     *
324     * <p> This method establishes an ordering for
325     * <a href="package-summary.html#reachability"><em>strong reachability</em></a>
326     * with respect to garbage collection.  It controls relations that are
327     * otherwise only implicit in a program -- the reachability conditions
328     * triggering garbage collection.  This method is designed for use in
329     * uncommon situations of premature finalization where using
330     * {@code synchronized} blocks or methods, or using other synchronization
331     * facilities are not possible or do not provide the desired control.  This
332     * method is applicable only when reclamation may have visible effects,
333     * which is possible for objects with finalizers (See
334     * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.6">
335     * Section 12.6 17 of <cite>The Java&trade; Language Specification</cite></a>)
336     * that are implemented in ways that rely on ordering control for correctness.
337     *
338     * @apiNote
339     * Finalization may occur whenever the virtual machine detects that no
340     * reference to an object will ever be stored in the heap: The garbage
341     * collector may reclaim an object even if the fields of that object are
342     * still in use, so long as the object has otherwise become unreachable.
343     * This may have surprising and undesirable effects in cases such as the
344     * following example in which the bookkeeping associated with a class is
345     * managed through array indices.  Here, method {@code action} uses a
346     * {@code reachabilityFence} to ensure that the {@code Resource} object is
347     * not reclaimed before bookkeeping on an associated
348     * {@code ExternalResource} has been performed; in particular here, to
349     * ensure that the array slot holding the {@code ExternalResource} is not
350     * nulled out in method {@link Object#finalize}, which may otherwise run
351     * concurrently.
352     *
353     * <pre> {@code
354     * class Resource {
355     *   private static ExternalResource[] externalResourceArray = ...
356     *
357     *   int myIndex;
358     *   Resource(...) {
359     *     myIndex = ...
360     *     externalResourceArray[myIndex] = ...;
361     *     ...
362     *   }
363     *   protected void finalize() {
364     *     externalResourceArray[myIndex] = null;
365     *     ...
366     *   }
367     *   public void action() {
368     *     try {
369     *       // ...
370     *       int i = myIndex;
371     *       Resource.update(externalResourceArray[i]);
372     *     } finally {
373     *       Reference.reachabilityFence(this);
374     *     }
375     *   }
376     *   private static void update(ExternalResource ext) {
377     *     ext.status = ...;
378     *   }
379     * }}</pre>
380     *
381     * Here, the invocation of {@code reachabilityFence} is nonintuitively
382     * placed <em>after</em> the call to {@code update}, to ensure that the
383     * array slot is not nulled out by {@link Object#finalize} before the
384     * update, even if the call to {@code action} was the last use of this
385     * object.  This might be the case if, for example a usage in a user program
386     * had the form {@code new Resource().action();} which retains no other
387     * reference to this {@code Resource}.  While probably overkill here,
388     * {@code reachabilityFence} is placed in a {@code finally} block to ensure
389     * that it is invoked across all paths in the method.  In a method with more
390     * complex control paths, you might need further precautions to ensure that
391     * {@code reachabilityFence} is encountered along all of them.
392     *
393     * <p> It is sometimes possible to better encapsulate use of
394     * {@code reachabilityFence}.  Continuing the above example, if it were
395     * acceptable for the call to method {@code update} to proceed even if the
396     * finalizer had already executed (nulling out slot), then you could
397     * localize use of {@code reachabilityFence}:
398     *
399     * <pre> {@code
400     * public void action2() {
401     *   // ...
402     *   Resource.update(getExternalResource());
403     * }
404     * private ExternalResource getExternalResource() {
405     *   ExternalResource ext = externalResourceArray[myIndex];
406     *   Reference.reachabilityFence(this);
407     *   return ext;
408     * }}</pre>
409     *
410     * <p> Method {@code reachabilityFence} is not required in constructions
411     * that themselves ensure reachability.  For example, because objects that
412     * are locked cannot, in general, be reclaimed, it would suffice if all
413     * accesses of the object, in all methods of class {@code Resource}
414     * (including {@code finalize}) were enclosed in {@code synchronized (this)}
415     * blocks.  (Further, such blocks must not include infinite loops, or
416     * themselves be unreachable, which fall into the corner case exceptions to
417     * the "in general" disclaimer.)  However, method {@code reachabilityFence}
418     * remains a better option in cases where this approach is not as efficient,
419     * desirable, or possible; for example because it would encounter deadlock.
420     *
421     * @param ref the reference. If {@code null}, this method has no effect.
422     * @since 9
423     */
424    @DontInline
425    public static void reachabilityFence(Object ref) {
426        // Does nothing, because this method is annotated with @DontInline
427        // HotSpot needs to retain the ref and not GC it before a call to this
428        // method
429    }
430
431}
432