/*
* 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.
*
*
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.
*
*
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 root set 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).
*
*
*
* Strongly reachable |
*
* - 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.
*
* |
*
*
*
* Softly reachable |
*
* - The object is not strongly reachable.
* - 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.
* |
*
*
*
* Weakly reachable |
*
* - The object is neither strongly nor softly reachable.
* - 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.
* |
*
*
*
* Phantom-reachable |
*
* - The object is neither strongly, softly, nor weakly reachable.
* - The object is referenced by a {@code java.lang.ref.PhantomReference} instance.
* - The object has already been finalized.
* |
*
*
*/
public abstract class Reference {
/**
* 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 must 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 must 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 must 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;
}
}