/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package java.lang.ref; /** * Provides an abstract class which describes behavior common to all reference * objects. It is not possible to create immediate subclasses of * {@code Reference} in addition to the ones provided by this package. It is * also not desirable to do so, since references require very close cooperation * with the system's garbage collector. The existing, specialized reference * classes should be used instead. * * <p>Three different type of references exist, each being weaker than the preceding one: * {@link java.lang.ref.SoftReference}, {@link java.lang.ref.WeakReference}, and * {@link java.lang.ref.PhantomReference}. "Weakness" here means that less restrictions are * being imposed on the garbage collector as to when it is allowed to * actually garbage-collect the referenced object. * * <p>In order to use reference objects properly it is important to understand * the different types of reachability that trigger their clearing and * enqueueing. The following table lists these, from strongest to weakest. * For each row, an object is said to have the reachability on the left side * if (and only if) it fulfills all of the requirements on the right side. In * all rows, consider the <em>root set</em> to be a set of references that * are "resistant" to garbage collection (that is, running threads, method * parameters, local variables, static fields and the like). * * <p><table> * <tr> * <td>Strongly reachable</td> * <td> <ul> * <li>There exists at least one path from the root set to the object that does not traverse any * instance of a {@code java.lang.ref.Reference} subclass. * </li> * </ul> </td> * </tr> * * <tr> * <td>Softly reachable</td> * <td> <ul> * <li>The object is not strongly reachable.</li> * <li>There exists at least one path from the root set to the object that does traverse * a {@code java.lang.ref.SoftReference} instance, but no {@code java.lang.ref.WeakReference} * or {@code java.lang.ref.PhantomReference} instances.</li> * </ul> </td> * </tr> * * <tr> * <td>Weakly reachable</td> * <td> <ul> * <li>The object is neither strongly nor softly reachable.</li> * <li>There exists at least one path from the root set to the object that does traverse a * {@code java.lang.ref.WeakReference} instance, but no {@code java.lang.ref.PhantomReference} * instances.</li> * </ul> </td> * </tr> * * <tr> * <td>Phantom-reachable</td> * <td> <ul> * <li>The object is neither strongly, softly, nor weakly reachable.</li> * <li>The object is referenced by a {@code java.lang.ref.PhantomReference} instance.</li> * <li>The object has already been finalized.</li> * </ul> </td> * </tr> * </table> */ public abstract class Reference<T> { /** * Forces JNI path. * If GC is not in progress (ie: not going through slow path), the referent * can be quickly returned through intrinsic without passing through JNI. * This flag forces the JNI path so that it can be tested and benchmarked. */ private static boolean disableIntrinsic = false; /** * Slow path flag for the reference processor. * Used by the reference processor to determine whether or not the referent * can be immediately returned. Because the referent might get swept during * GC, the slow path, which passes through JNI, must be taken. */ private static boolean slowPathEnabled = false; /** * The object to which this reference refers. * VM requirement: this field <em>must</em> be called "referent" * and be an object. */ volatile T referent; /** * If non-null, the queue on which this reference will be enqueued * when the referent is appropriately reachable. * VM requirement: this field <em>must</em> be called "queue" * and be a java.lang.ref.ReferenceQueue. */ volatile ReferenceQueue<? super T> queue; /** * Used internally by java.lang.ref.ReferenceQueue. * VM requirement: this field <em>must</em> be called "queueNext" * and be a java.lang.ref.Reference. */ @SuppressWarnings("unchecked") volatile Reference queueNext; /** * Used internally by the VM. This field forms a circular and * singly linked list of reference objects discovered by the * garbage collector and awaiting processing by the reference * queue thread. * * @hide */ public volatile Reference<?> pendingNext; /** * Constructs a new instance of this class. */ Reference() { } Reference(T r, ReferenceQueue<? super T> q) { referent = r; queue = q; } /** * Makes the referent {@code null}. This does not force the reference * object to be enqueued. */ public void clear() { referent = null; } /** * Adds an object to its reference queue. * * @return {@code true} if this call has caused the {@code Reference} to * become enqueued, or {@code false} otherwise * * @hide */ public final synchronized boolean enqueueInternal() { if (queue != null && queueNext == null) { queue.enqueue(this); queue = null; return true; } return false; } /** * Forces the reference object to be enqueued if it has been associated with * a queue. * * @return {@code true} if this call has caused the {@code Reference} to * become enqueued, or {@code false} otherwise */ public boolean enqueue() { return enqueueInternal(); } /** * Returns the referent of the reference object. * * @return the referent to which reference refers, or {@code null} if the * object has been cleared. */ public T get() { return getReferent(); } /** * Returns the referent of the reference object. * * @return the referent to which reference refers, or {@code null} if the * object has been cleared. Required since the compiler * intrisifies getReferent() since we can't intrinsify Reference.get() * due to incorrect devirtualization (and inlining) of PhantomReference.get(). */ private final native T getReferent(); /** * Checks whether the reference object has been enqueued. * * @return {@code true} if the {@code Reference} has been enqueued, {@code * false} otherwise */ public boolean isEnqueued() { return queueNext != null; } }