Reference.java revision 15606:ad6acec2501b
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
23 * questions.
24 */
25
26package java.lang.ref;
27
28import jdk.internal.vm.annotation.DontInline;
29import jdk.internal.HotSpotIntrinsicCandidate;
30import jdk.internal.misc.JavaLangRefAccess;
31import jdk.internal.misc.SharedSecrets;
32import 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
44public 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        }
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;
172            ref.discovered = null;
173
174            if (ref instanceof Cleaner) {
175                ((Cleaner)ref).clean();
176                // Notify any waiters that progress has been made.
177                // This improves latency for nio.Bits waiters, which
178                // are the only important ones.
179                synchronized (processPendingLock) {
180                    processPendingLock.notifyAll();
181                }
182            } else {
183                ReferenceQueue<? super Object> q = ref.queue;
184                if (q != ReferenceQueue.NULL) q.enqueue(ref);
185            }
186        }
187        // Notify any waiters of completion of current round.
188        synchronized (processPendingLock) {
189            processPendingActive = false;
190            processPendingLock.notifyAll();
191        }
192    }
193
194    // Wait for progress in reference processing.
195    //
196    // Returns true after waiting (for notification from the reference
197    // processing thread) if either (1) the VM has any pending
198    // references, or (2) the reference processing thread is
199    // processing references. Otherwise, returns false immediately.
200    private static boolean waitForReferenceProcessing()
201        throws InterruptedException
202    {
203        synchronized (processPendingLock) {
204            if (processPendingActive || hasReferencePendingList()) {
205                // Wait for progress, not necessarily completion.
206                processPendingLock.wait();
207                return true;
208            } else {
209                return false;
210            }
211        }
212    }
213
214    static {
215        ThreadGroup tg = Thread.currentThread().getThreadGroup();
216        for (ThreadGroup tgn = tg;
217             tgn != null;
218             tg = tgn, tgn = tg.getParent());
219        Thread handler = new ReferenceHandler(tg, "Reference Handler");
220        /* If there were a special system-only priority greater than
221         * MAX_PRIORITY, it would be used here
222         */
223        handler.setPriority(Thread.MAX_PRIORITY);
224        handler.setDaemon(true);
225        handler.start();
226
227        // provide access in SharedSecrets
228        SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {
229            @Override
230            public boolean waitForReferenceProcessing()
231                throws InterruptedException
232            {
233                return Reference.waitForReferenceProcessing();
234            }
235        });
236    }
237
238    /* -- Referent accessor and setters -- */
239
240    /**
241     * Returns this reference object's referent.  If this reference object has
242     * been cleared, either by the program or by the garbage collector, then
243     * this method returns <code>null</code>.
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     *
316     * <p> This method establishes an ordering for
317     * <a href="package-summary.html#reachability"><em>strong reachability</em></a>
318     * with respect to garbage collection.  It controls relations that are
319     * otherwise only implicit in a program -- the reachability conditions
320     * triggering garbage collection.  This method is designed for use in
321     * uncommon situations of premature finalization where using
322     * {@code synchronized} blocks or methods, or using other synchronization
323     * facilities are not possible or do not provide the desired control.  This
324     * method is applicable only when reclamation may have visible effects,
325     * which is possible for objects with finalizers (See
326     * <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-12.html#jls-12.6">
327     * Section 12.6 17 of <cite>The Java&trade; Language Specification</cite></a>)
328     * that are implemented in ways that rely on ordering control for correctness.
329     *
330     * @apiNote
331     * Finalization may occur whenever the virtual machine detects that no
332     * reference to an object will ever be stored in the heap: The garbage
333     * collector may reclaim an object even if the fields of that object are
334     * still in use, so long as the object has otherwise become unreachable.
335     * This may have surprising and undesirable effects in cases such as the
336     * following example in which the bookkeeping associated with a class is
337     * managed through array indices.  Here, method {@code action} uses a
338     * {@code reachabilityFence} to ensure that the {@code Resource} object is
339     * not reclaimed before bookkeeping on an associated
340     * {@code ExternalResource} has been performed; in particular here, to
341     * ensure that the array slot holding the {@code ExternalResource} is not
342     * nulled out in method {@link Object#finalize}, which may otherwise run
343     * concurrently.
344     *
345     * <pre> {@code
346     * class Resource {
347     *   private static ExternalResource[] externalResourceArray = ...
348     *
349     *   int myIndex;
350     *   Resource(...) {
351     *     myIndex = ...
352     *     externalResourceArray[myIndex] = ...;
353     *     ...
354     *   }
355     *   protected void finalize() {
356     *     externalResourceArray[myIndex] = null;
357     *     ...
358     *   }
359     *   public void action() {
360     *     try {
361     *       // ...
362     *       int i = myIndex;
363     *       Resource.update(externalResourceArray[i]);
364     *     } finally {
365     *       Reference.reachabilityFence(this);
366     *     }
367     *   }
368     *   private static void update(ExternalResource ext) {
369     *     ext.status = ...;
370     *   }
371     * }}</pre>
372     *
373     * Here, the invocation of {@code reachabilityFence} is nonintuitively
374     * placed <em>after</em> the call to {@code update}, to ensure that the
375     * array slot is not nulled out by {@link Object#finalize} before the
376     * update, even if the call to {@code action} was the last use of this
377     * object.  This might be the case if, for example a usage in a user program
378     * had the form {@code new Resource().action();} which retains no other
379     * reference to this {@code Resource}.  While probably overkill here,
380     * {@code reachabilityFence} is placed in a {@code finally} block to ensure
381     * that it is invoked across all paths in the method.  In a method with more
382     * complex control paths, you might need further precautions to ensure that
383     * {@code reachabilityFence} is encountered along all of them.
384     *
385     * <p> It is sometimes possible to better encapsulate use of
386     * {@code reachabilityFence}.  Continuing the above example, if it were
387     * acceptable for the call to method {@code update} to proceed even if the
388     * finalizer had already executed (nulling out slot), then you could
389     * localize use of {@code reachabilityFence}:
390     *
391     * <pre> {@code
392     * public void action2() {
393     *   // ...
394     *   Resource.update(getExternalResource());
395     * }
396     * private ExternalResource getExternalResource() {
397     *   ExternalResource ext = externalResourceArray[myIndex];
398     *   Reference.reachabilityFence(this);
399     *   return ext;
400     * }}</pre>
401     *
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}
424