feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
41
jdkSrc/jdk8/java/lang/ref/FinalReference.java
Normal file
41
jdkSrc/jdk8/java/lang/ref/FinalReference.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.ref;
|
||||
|
||||
/**
|
||||
* Final references, used to implement finalization
|
||||
*/
|
||||
class FinalReference<T> extends Reference<T> {
|
||||
|
||||
public FinalReference(T referent, ReferenceQueue<? super T> q) {
|
||||
super(referent, q);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enqueue() {
|
||||
throw new InternalError("should never reach here");
|
||||
}
|
||||
}
|
||||
208
jdkSrc/jdk8/java/lang/ref/Finalizer.java
Normal file
208
jdkSrc/jdk8/java/lang/ref/Finalizer.java
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.ref;
|
||||
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.AccessController;
|
||||
import sun.misc.JavaLangAccess;
|
||||
import sun.misc.SharedSecrets;
|
||||
import sun.misc.VM;
|
||||
|
||||
final class Finalizer extends FinalReference<Object> { /* Package-private; must be in
|
||||
same package as the Reference
|
||||
class */
|
||||
|
||||
private static ReferenceQueue<Object> queue = new ReferenceQueue<>();
|
||||
private static Finalizer unfinalized = null;
|
||||
private static final Object lock = new Object();
|
||||
|
||||
private Finalizer
|
||||
next = null,
|
||||
prev = null;
|
||||
|
||||
private boolean hasBeenFinalized() {
|
||||
return (next == this);
|
||||
}
|
||||
|
||||
private void add() {
|
||||
synchronized (lock) {
|
||||
if (unfinalized != null) {
|
||||
this.next = unfinalized;
|
||||
unfinalized.prev = this;
|
||||
}
|
||||
unfinalized = this;
|
||||
}
|
||||
}
|
||||
|
||||
private void remove() {
|
||||
synchronized (lock) {
|
||||
if (unfinalized == this) {
|
||||
if (this.next != null) {
|
||||
unfinalized = this.next;
|
||||
} else {
|
||||
unfinalized = this.prev;
|
||||
}
|
||||
}
|
||||
if (this.next != null) {
|
||||
this.next.prev = this.prev;
|
||||
}
|
||||
if (this.prev != null) {
|
||||
this.prev.next = this.next;
|
||||
}
|
||||
this.next = this; /* Indicates that this has been finalized */
|
||||
this.prev = this;
|
||||
}
|
||||
}
|
||||
|
||||
private Finalizer(Object finalizee) {
|
||||
super(finalizee, queue);
|
||||
add();
|
||||
}
|
||||
|
||||
static ReferenceQueue<Object> getQueue() {
|
||||
return queue;
|
||||
}
|
||||
|
||||
/* Invoked by VM */
|
||||
static void register(Object finalizee) {
|
||||
new Finalizer(finalizee);
|
||||
}
|
||||
|
||||
private void runFinalizer(JavaLangAccess jla) {
|
||||
synchronized (this) {
|
||||
if (hasBeenFinalized()) return;
|
||||
remove();
|
||||
}
|
||||
try {
|
||||
Object finalizee = this.get();
|
||||
if (finalizee != null && !(finalizee instanceof java.lang.Enum)) {
|
||||
jla.invokeFinalize(finalizee);
|
||||
|
||||
/* Clear stack slot containing this variable, to decrease
|
||||
the chances of false retention with a conservative GC */
|
||||
finalizee = null;
|
||||
}
|
||||
} catch (Throwable x) { }
|
||||
super.clear();
|
||||
}
|
||||
|
||||
/* Create a privileged secondary finalizer thread in the system thread
|
||||
group for the given Runnable, and wait for it to complete.
|
||||
|
||||
This method is used by runFinalization.
|
||||
|
||||
It could have been implemented by offloading the work to the
|
||||
regular finalizer thread and waiting for that thread to finish.
|
||||
The advantage of creating a fresh thread, however, is that it insulates
|
||||
invokers of that method from a stalled or deadlocked finalizer thread.
|
||||
*/
|
||||
private static void forkSecondaryFinalizer(final Runnable proc) {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
ThreadGroup tg = Thread.currentThread().getThreadGroup();
|
||||
for (ThreadGroup tgn = tg;
|
||||
tgn != null;
|
||||
tg = tgn, tgn = tg.getParent());
|
||||
Thread sft = new Thread(tg, proc, "Secondary finalizer");
|
||||
sft.start();
|
||||
try {
|
||||
sft.join();
|
||||
} catch (InterruptedException x) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
return null;
|
||||
}});
|
||||
}
|
||||
|
||||
/* Called by Runtime.runFinalization() */
|
||||
static void runFinalization() {
|
||||
if (!VM.isBooted()) {
|
||||
return;
|
||||
}
|
||||
|
||||
forkSecondaryFinalizer(new Runnable() {
|
||||
private volatile boolean running;
|
||||
public void run() {
|
||||
// in case of recursive call to run()
|
||||
if (running)
|
||||
return;
|
||||
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
|
||||
running = true;
|
||||
for (;;) {
|
||||
Finalizer f = (Finalizer)queue.poll();
|
||||
if (f == null) break;
|
||||
f.runFinalizer(jla);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class FinalizerThread extends Thread {
|
||||
private volatile boolean running;
|
||||
FinalizerThread(ThreadGroup g) {
|
||||
super(g, "Finalizer");
|
||||
}
|
||||
public void run() {
|
||||
// in case of recursive call to run()
|
||||
if (running)
|
||||
return;
|
||||
|
||||
// Finalizer thread starts before System.initializeSystemClass
|
||||
// is called. Wait until JavaLangAccess is available
|
||||
while (!VM.isBooted()) {
|
||||
// delay until VM completes initialization
|
||||
try {
|
||||
VM.awaitBooted();
|
||||
} catch (InterruptedException x) {
|
||||
// ignore and continue
|
||||
}
|
||||
}
|
||||
final JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
|
||||
running = true;
|
||||
for (;;) {
|
||||
try {
|
||||
Finalizer f = (Finalizer)queue.remove();
|
||||
f.runFinalizer(jla);
|
||||
} catch (InterruptedException x) {
|
||||
// ignore and continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
ThreadGroup tg = Thread.currentThread().getThreadGroup();
|
||||
for (ThreadGroup tgn = tg;
|
||||
tgn != null;
|
||||
tg = tgn, tgn = tg.getParent());
|
||||
Thread finalizer = new FinalizerThread(tg);
|
||||
finalizer.setPriority(Thread.MAX_PRIORITY - 2);
|
||||
finalizer.setDaemon(true);
|
||||
finalizer.start();
|
||||
}
|
||||
|
||||
}
|
||||
80
jdkSrc/jdk8/java/lang/ref/FinalizerHistogram.java
Normal file
80
jdkSrc/jdk8/java/lang/ref/FinalizerHistogram.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.ref;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* This FinalizerHistogram class is for GC.finalizer_info diagnostic command support.
|
||||
* It is invoked by the VM.
|
||||
*/
|
||||
|
||||
final class FinalizerHistogram {
|
||||
|
||||
private static final class Entry {
|
||||
private int instanceCount;
|
||||
private final String className;
|
||||
|
||||
int getInstanceCount() {
|
||||
return instanceCount;
|
||||
}
|
||||
|
||||
void increment() {
|
||||
instanceCount += 1;
|
||||
}
|
||||
|
||||
Entry(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
}
|
||||
|
||||
// Method below is called by VM and VM expect certain
|
||||
// entry class layout.
|
||||
|
||||
static Entry[] getFinalizerHistogram() {
|
||||
Map<String, Entry> countMap = new HashMap<>();
|
||||
ReferenceQueue<Object> queue = Finalizer.getQueue();
|
||||
queue.forEach(r -> {
|
||||
Object referent = r.get();
|
||||
if (referent != null) {
|
||||
countMap.computeIfAbsent(
|
||||
referent.getClass().getName(), Entry::new).increment();
|
||||
/* Clear stack slot containing this variable, to decrease
|
||||
the chances of false retention with a conservative GC */
|
||||
referent = null;
|
||||
}
|
||||
});
|
||||
|
||||
Entry fhe[] = countMap.values().toArray(new Entry[countMap.size()]);
|
||||
Arrays.sort(fhe,
|
||||
Comparator.comparingInt(Entry::getInstanceCount).reversed());
|
||||
return fhe;
|
||||
}
|
||||
}
|
||||
80
jdkSrc/jdk8/java/lang/ref/PhantomReference.java
Normal file
80
jdkSrc/jdk8/java/lang/ref/PhantomReference.java
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.ref;
|
||||
|
||||
|
||||
/**
|
||||
* Phantom reference objects, which are enqueued after the collector
|
||||
* determines that their referents may otherwise be reclaimed. Phantom
|
||||
* references are most often used to schedule post-mortem cleanup actions.
|
||||
*
|
||||
* <p> Suppose the garbage collector determines at a certain point in time
|
||||
* that an object is <a href="package-summary.html#reachability">
|
||||
* phantom reachable</a>. At that time it will atomically clear
|
||||
* all phantom references to that object and all phantom references to
|
||||
* any other phantom-reachable objects from which that object is reachable.
|
||||
* At the same time or at some later time it will enqueue those newly-cleared
|
||||
* phantom references that are registered with reference queues.
|
||||
*
|
||||
* <p> In order to ensure that a reclaimable object remains so, the referent of
|
||||
* a phantom reference may not be retrieved: The <code>get</code> method of a
|
||||
* phantom reference always returns <code>null</code>.
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public class PhantomReference<T> extends Reference<T> {
|
||||
|
||||
/**
|
||||
* Returns this reference object's referent. Because the referent of a
|
||||
* phantom reference is always inaccessible, this method always returns
|
||||
* <code>null</code>.
|
||||
*
|
||||
* @return <code>null</code>
|
||||
*/
|
||||
public T get() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new phantom reference that refers to the given object and
|
||||
* is registered with the given queue.
|
||||
*
|
||||
* <p> It is possible to create a phantom reference with a <tt>null</tt>
|
||||
* queue, but such a reference is completely useless: Its <tt>get</tt>
|
||||
* method will always return {@code null} and, since it does not have a queue,
|
||||
* it will never be enqueued.
|
||||
*
|
||||
* @param referent the object the new phantom reference will refer to
|
||||
* @param q the queue with which the reference is to be registered,
|
||||
* or <tt>null</tt> if registration is not required
|
||||
*/
|
||||
public PhantomReference(T referent, ReferenceQueue<? super T> q) {
|
||||
super(referent, q);
|
||||
}
|
||||
|
||||
}
|
||||
326
jdkSrc/jdk8/java/lang/ref/Reference.java
Normal file
326
jdkSrc/jdk8/java/lang/ref/Reference.java
Normal file
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.ref;
|
||||
|
||||
import sun.misc.Cleaner;
|
||||
import sun.misc.JavaLangRefAccess;
|
||||
import sun.misc.SharedSecrets;
|
||||
|
||||
/**
|
||||
* Abstract base class for reference objects. This class defines the
|
||||
* operations common to all reference objects. Because reference objects are
|
||||
* implemented in close cooperation with the garbage collector, this class may
|
||||
* not be subclassed directly.
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public abstract class Reference<T> {
|
||||
|
||||
/* A Reference instance is in one of four possible internal states:
|
||||
*
|
||||
* Active: Subject to special treatment by the garbage collector. Some
|
||||
* time after the collector detects that the reachability of the
|
||||
* referent has changed to the appropriate state, it changes the
|
||||
* instance's state to either Pending or Inactive, depending upon
|
||||
* whether or not the instance was registered with a queue when it was
|
||||
* created. In the former case it also adds the instance to the
|
||||
* pending-Reference list. Newly-created instances are Active.
|
||||
*
|
||||
* Pending: An element of the pending-Reference list, waiting to be
|
||||
* enqueued by the Reference-handler thread. Unregistered instances
|
||||
* are never in this state.
|
||||
*
|
||||
* Enqueued: An element of the queue with which the instance was
|
||||
* registered when it was created. When an instance is removed from
|
||||
* its ReferenceQueue, it is made Inactive. Unregistered instances are
|
||||
* never in this state.
|
||||
*
|
||||
* Inactive: Nothing more to do. Once an instance becomes Inactive its
|
||||
* state will never change again.
|
||||
*
|
||||
* The state is encoded in the queue and next fields as follows:
|
||||
*
|
||||
* Active: queue = ReferenceQueue with which instance is registered, or
|
||||
* ReferenceQueue.NULL if it was not registered with a queue; next =
|
||||
* null.
|
||||
*
|
||||
* Pending: queue = ReferenceQueue with which instance is registered;
|
||||
* next = this
|
||||
*
|
||||
* Enqueued: queue = ReferenceQueue.ENQUEUED; next = Following instance
|
||||
* in queue, or this if at end of list.
|
||||
*
|
||||
* Inactive: queue = ReferenceQueue.NULL; next = this.
|
||||
*
|
||||
* With this scheme the collector need only examine the next field in order
|
||||
* to determine whether a Reference instance requires special treatment: If
|
||||
* the next field is null then the instance is active; if it is non-null,
|
||||
* then the collector should treat the instance normally.
|
||||
*
|
||||
* To ensure that a concurrent collector can discover active Reference
|
||||
* objects without interfering with application threads that may apply
|
||||
* the enqueue() method to those objects, collectors should link
|
||||
* discovered objects through the discovered field. The discovered
|
||||
* field is also used for linking Reference objects in the pending list.
|
||||
*/
|
||||
|
||||
private T referent; /* Treated specially by GC */
|
||||
|
||||
volatile ReferenceQueue<? super T> queue;
|
||||
|
||||
/* When active: NULL
|
||||
* pending: this
|
||||
* Enqueued: next reference in queue (or this if last)
|
||||
* Inactive: this
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
volatile Reference next;
|
||||
|
||||
/* When active: next element in a discovered reference list maintained by GC (or this if last)
|
||||
* pending: next element in the pending list (or null if last)
|
||||
* otherwise: NULL
|
||||
*/
|
||||
transient private Reference<T> discovered; /* used by VM */
|
||||
|
||||
|
||||
/* Object used to synchronize with the garbage collector. The collector
|
||||
* must acquire this lock at the beginning of each collection cycle. It is
|
||||
* therefore critical that any code holding this lock complete as quickly
|
||||
* as possible, allocate no new objects, and avoid calling user code.
|
||||
*/
|
||||
static private class Lock { }
|
||||
private static Lock lock = new Lock();
|
||||
|
||||
|
||||
/* List of References waiting to be enqueued. The collector adds
|
||||
* References to this list, while the Reference-handler thread removes
|
||||
* them. This list is protected by the above lock object. The
|
||||
* list uses the discovered field to link its elements.
|
||||
*/
|
||||
private static Reference<Object> pending = null;
|
||||
|
||||
/* High-priority thread to enqueue pending References
|
||||
*/
|
||||
private static class ReferenceHandler extends Thread {
|
||||
|
||||
private static void ensureClassInitialized(Class<?> clazz) {
|
||||
try {
|
||||
Class.forName(clazz.getName(), true, clazz.getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw (Error) new NoClassDefFoundError(e.getMessage()).initCause(e);
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
// pre-load and initialize InterruptedException and Cleaner classes
|
||||
// so that we don't get into trouble later in the run loop if there's
|
||||
// memory shortage while loading/initializing them lazily.
|
||||
ensureClassInitialized(InterruptedException.class);
|
||||
ensureClassInitialized(Cleaner.class);
|
||||
}
|
||||
|
||||
ReferenceHandler(ThreadGroup g, String name) {
|
||||
super(g, name);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
tryHandlePending(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try handle pending {@link Reference} if there is one.<p>
|
||||
* Return {@code true} as a hint that there might be another
|
||||
* {@link Reference} pending or {@code false} when there are no more pending
|
||||
* {@link Reference}s at the moment and the program can do some other
|
||||
* useful work instead of looping.
|
||||
*
|
||||
* @param waitForNotify if {@code true} and there was no pending
|
||||
* {@link Reference}, wait until notified from VM
|
||||
* or interrupted; if {@code false}, return immediately
|
||||
* when there is no pending {@link Reference}.
|
||||
* @return {@code true} if there was a {@link Reference} pending and it
|
||||
* was processed, or we waited for notification and either got it
|
||||
* or thread was interrupted before being notified;
|
||||
* {@code false} otherwise.
|
||||
*/
|
||||
static boolean tryHandlePending(boolean waitForNotify) {
|
||||
Reference<Object> r;
|
||||
Cleaner c;
|
||||
try {
|
||||
synchronized (lock) {
|
||||
if (pending != null) {
|
||||
r = pending;
|
||||
// 'instanceof' might throw OutOfMemoryError sometimes
|
||||
// so do this before un-linking 'r' from the 'pending' chain...
|
||||
c = r instanceof Cleaner ? (Cleaner) r : null;
|
||||
// unlink 'r' from 'pending' chain
|
||||
pending = r.discovered;
|
||||
r.discovered = null;
|
||||
} else {
|
||||
// The waiting on the lock may cause an OutOfMemoryError
|
||||
// because it may try to allocate exception objects.
|
||||
if (waitForNotify) {
|
||||
lock.wait();
|
||||
}
|
||||
// retry if waited
|
||||
return waitForNotify;
|
||||
}
|
||||
}
|
||||
} catch (OutOfMemoryError x) {
|
||||
// Give other threads CPU time so they hopefully drop some live references
|
||||
// and GC reclaims some space.
|
||||
// Also prevent CPU intensive spinning in case 'r instanceof Cleaner' above
|
||||
// persistently throws OOME for some time...
|
||||
Thread.yield();
|
||||
// retry
|
||||
return true;
|
||||
} catch (InterruptedException x) {
|
||||
// retry
|
||||
return true;
|
||||
}
|
||||
|
||||
// Fast path for cleaners
|
||||
if (c != null) {
|
||||
c.clean();
|
||||
return true;
|
||||
}
|
||||
|
||||
ReferenceQueue<? super Object> q = r.queue;
|
||||
if (q != ReferenceQueue.NULL) q.enqueue(r);
|
||||
return true;
|
||||
}
|
||||
|
||||
static {
|
||||
ThreadGroup tg = Thread.currentThread().getThreadGroup();
|
||||
for (ThreadGroup tgn = tg;
|
||||
tgn != null;
|
||||
tg = tgn, tgn = tg.getParent());
|
||||
Thread handler = new ReferenceHandler(tg, "Reference Handler");
|
||||
/* If there were a special system-only priority greater than
|
||||
* MAX_PRIORITY, it would be used here
|
||||
*/
|
||||
handler.setPriority(Thread.MAX_PRIORITY);
|
||||
handler.setDaemon(true);
|
||||
handler.start();
|
||||
|
||||
// provide access in SharedSecrets
|
||||
SharedSecrets.setJavaLangRefAccess(new JavaLangRefAccess() {
|
||||
@Override
|
||||
public boolean tryHandlePendingReference() {
|
||||
return tryHandlePending(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* -- Referent accessor and setters -- */
|
||||
|
||||
/**
|
||||
* Returns this reference object's referent. If this reference object has
|
||||
* been cleared, either by the program or by the garbage collector, then
|
||||
* this method returns <code>null</code>.
|
||||
*
|
||||
* @return The object to which this reference refers, or
|
||||
* <code>null</code> if this reference object has been cleared
|
||||
*/
|
||||
public T get() {
|
||||
return this.referent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears this reference object. Invoking this method will not cause this
|
||||
* object to be enqueued.
|
||||
*
|
||||
* <p> This method is invoked only by Java code; when the garbage collector
|
||||
* clears references it does so directly, without invoking this method.
|
||||
*/
|
||||
public void clear() {
|
||||
this.referent = null;
|
||||
}
|
||||
|
||||
/* -- Queue operations -- */
|
||||
|
||||
/**
|
||||
* Tells whether or not this reference object has been enqueued, either by
|
||||
* the program or by the garbage collector. If this reference object was
|
||||
* not registered with a queue when it was created, then this method will
|
||||
* always return <code>false</code>.
|
||||
*
|
||||
* @return <code>true</code> if and only if this reference object has
|
||||
* been enqueued
|
||||
*/
|
||||
public boolean isEnqueued() {
|
||||
return (this.queue == ReferenceQueue.ENQUEUED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears this reference object and adds it to the queue with which
|
||||
* it is registered, if any.
|
||||
*
|
||||
* <p> This method is invoked only by Java code; when the garbage collector
|
||||
* enqueues references it does so directly, without invoking this method.
|
||||
*
|
||||
* @return <code>true</code> if this reference object was successfully
|
||||
* enqueued; <code>false</code> if it was already enqueued or if
|
||||
* it was not registered with a queue when it was created
|
||||
*/
|
||||
public boolean enqueue() {
|
||||
this.referent = null;
|
||||
return this.queue.enqueue(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Throws {@link CloneNotSupportedException}. A {@code Reference} cannot be
|
||||
* meaningfully cloned. Construct a new {@code Reference} instead.
|
||||
*
|
||||
* @apiNote This method is defined in Java SE 8 Maintenance Release 4.
|
||||
*
|
||||
* @return never returns normally
|
||||
* @throws CloneNotSupportedException always
|
||||
*
|
||||
* @since 8
|
||||
*/
|
||||
@Override
|
||||
protected Object clone() throws CloneNotSupportedException {
|
||||
throw new CloneNotSupportedException();
|
||||
}
|
||||
|
||||
/* -- Constructors -- */
|
||||
|
||||
Reference(T referent) {
|
||||
this(referent, null);
|
||||
}
|
||||
|
||||
Reference(T referent, ReferenceQueue<? super T> queue) {
|
||||
this.referent = referent;
|
||||
this.queue = (queue == null) ? ReferenceQueue.NULL : queue;
|
||||
}
|
||||
}
|
||||
196
jdkSrc/jdk8/java/lang/ref/ReferenceQueue.java
Normal file
196
jdkSrc/jdk8/java/lang/ref/ReferenceQueue.java
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.ref;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* Reference queues, to which registered reference objects are appended by the
|
||||
* garbage collector after the appropriate reachability changes are detected.
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public class ReferenceQueue<T> {
|
||||
|
||||
/**
|
||||
* Constructs a new reference-object queue.
|
||||
*/
|
||||
public ReferenceQueue() { }
|
||||
|
||||
private static class Null<S> extends ReferenceQueue<S> {
|
||||
boolean enqueue(Reference<? extends S> r) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static ReferenceQueue<Object> NULL = new Null<>();
|
||||
static ReferenceQueue<Object> ENQUEUED = new Null<>();
|
||||
|
||||
static private class Lock { };
|
||||
private Lock lock = new Lock();
|
||||
private volatile Reference<? extends T> head = null;
|
||||
private long queueLength = 0;
|
||||
|
||||
boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
|
||||
synchronized (lock) {
|
||||
// Check that since getting the lock this reference hasn't already been
|
||||
// enqueued (and even then removed)
|
||||
ReferenceQueue<?> queue = r.queue;
|
||||
if ((queue == NULL) || (queue == ENQUEUED)) {
|
||||
return false;
|
||||
}
|
||||
assert queue == this;
|
||||
r.queue = ENQUEUED;
|
||||
r.next = (head == null) ? r : head;
|
||||
head = r;
|
||||
queueLength++;
|
||||
if (r instanceof FinalReference) {
|
||||
sun.misc.VM.addFinalRefCount(1);
|
||||
}
|
||||
lock.notifyAll();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private Reference<? extends T> reallyPoll() { /* Must hold lock */
|
||||
Reference<? extends T> r = head;
|
||||
if (r != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Reference<? extends T> rn = r.next;
|
||||
head = (rn == r) ? null : rn;
|
||||
r.queue = NULL;
|
||||
r.next = r;
|
||||
queueLength--;
|
||||
if (r instanceof FinalReference) {
|
||||
sun.misc.VM.addFinalRefCount(-1);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls this queue to see if a reference object is available. If one is
|
||||
* available without further delay then it is removed from the queue and
|
||||
* returned. Otherwise this method immediately returns <tt>null</tt>.
|
||||
*
|
||||
* @return A reference object, if one was immediately available,
|
||||
* otherwise <code>null</code>
|
||||
*/
|
||||
public Reference<? extends T> poll() {
|
||||
if (head == null)
|
||||
return null;
|
||||
synchronized (lock) {
|
||||
return reallyPoll();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the next reference object in this queue, blocking until either
|
||||
* one becomes available or the given timeout period expires.
|
||||
*
|
||||
* <p> This method does not offer real-time guarantees: It schedules the
|
||||
* timeout as if by invoking the {@link Object#wait(long)} method.
|
||||
*
|
||||
* @param timeout If positive, block for up to <code>timeout</code>
|
||||
* milliseconds while waiting for a reference to be
|
||||
* added to this queue. If zero, block indefinitely.
|
||||
*
|
||||
* @return A reference object, if one was available within the specified
|
||||
* timeout period, otherwise <code>null</code>
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If the value of the timeout argument is negative
|
||||
*
|
||||
* @throws InterruptedException
|
||||
* If the timeout wait is interrupted
|
||||
*/
|
||||
public Reference<? extends T> remove(long timeout)
|
||||
throws IllegalArgumentException, InterruptedException
|
||||
{
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("Negative timeout value");
|
||||
}
|
||||
synchronized (lock) {
|
||||
Reference<? extends T> r = reallyPoll();
|
||||
if (r != null) return r;
|
||||
long start = (timeout == 0) ? 0 : System.nanoTime();
|
||||
for (;;) {
|
||||
lock.wait(timeout);
|
||||
r = reallyPoll();
|
||||
if (r != null) return r;
|
||||
if (timeout != 0) {
|
||||
long end = System.nanoTime();
|
||||
timeout -= (end - start) / 1000_000;
|
||||
if (timeout <= 0) return null;
|
||||
start = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the next reference object in this queue, blocking until one
|
||||
* becomes available.
|
||||
*
|
||||
* @return A reference object, blocking until one becomes available
|
||||
* @throws InterruptedException If the wait is interrupted
|
||||
*/
|
||||
public Reference<? extends T> remove() throws InterruptedException {
|
||||
return remove(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate queue and invoke given action with each Reference.
|
||||
* Suitable for diagnostic purposes.
|
||||
* WARNING: any use of this method should make sure to not
|
||||
* retain the referents of iterated references (in case of
|
||||
* FinalReference(s)) so that their life is not prolonged more
|
||||
* than necessary.
|
||||
*/
|
||||
void forEach(Consumer<? super Reference<? extends T>> action) {
|
||||
for (Reference<? extends T> r = head; r != null;) {
|
||||
action.accept(r);
|
||||
@SuppressWarnings("unchecked")
|
||||
Reference<? extends T> rn = r.next;
|
||||
if (rn == r) {
|
||||
if (r.queue == ENQUEUED) {
|
||||
// still enqueued -> we reached end of chain
|
||||
r = null;
|
||||
} else {
|
||||
// already dequeued: r.queue == NULL; ->
|
||||
// restart from head when overtaken by queue poller(s)
|
||||
r = head;
|
||||
}
|
||||
} else {
|
||||
// next in chain
|
||||
r = rn;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
118
jdkSrc/jdk8/java/lang/ref/SoftReference.java
Normal file
118
jdkSrc/jdk8/java/lang/ref/SoftReference.java
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.ref;
|
||||
|
||||
|
||||
/**
|
||||
* Soft reference objects, which are cleared at the discretion of the garbage
|
||||
* collector in response to memory demand. Soft references are most often used
|
||||
* to implement memory-sensitive caches.
|
||||
*
|
||||
* <p> Suppose that the garbage collector determines at a certain point in time
|
||||
* that an object is <a href="package-summary.html#reachability">softly
|
||||
* reachable</a>. At that time it may choose to clear atomically all soft
|
||||
* references to that object and all soft references to any other
|
||||
* softly-reachable objects from which that object is reachable through a chain
|
||||
* of strong references. At the same time or at some later time it will
|
||||
* enqueue those newly-cleared soft references that are registered with
|
||||
* reference queues.
|
||||
*
|
||||
* <p> All soft references to softly-reachable objects are guaranteed to have
|
||||
* been cleared before the virtual machine throws an
|
||||
* <code>OutOfMemoryError</code>. Otherwise no constraints are placed upon the
|
||||
* time at which a soft reference will be cleared or the order in which a set
|
||||
* of such references to different objects will be cleared. Virtual machine
|
||||
* implementations are, however, encouraged to bias against clearing
|
||||
* recently-created or recently-used soft references.
|
||||
*
|
||||
* <p> Direct instances of this class may be used to implement simple caches;
|
||||
* this class or derived subclasses may also be used in larger data structures
|
||||
* to implement more sophisticated caches. As long as the referent of a soft
|
||||
* reference is strongly reachable, that is, is actually in use, the soft
|
||||
* reference will not be cleared. Thus a sophisticated cache can, for example,
|
||||
* prevent its most recently used entries from being discarded by keeping
|
||||
* strong referents to those entries, leaving the remaining entries to be
|
||||
* discarded at the discretion of the garbage collector.
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public class SoftReference<T> extends Reference<T> {
|
||||
|
||||
/**
|
||||
* Timestamp clock, updated by the garbage collector
|
||||
*/
|
||||
static private long clock;
|
||||
|
||||
/**
|
||||
* Timestamp updated by each invocation of the get method. The VM may use
|
||||
* this field when selecting soft references to be cleared, but it is not
|
||||
* required to do so.
|
||||
*/
|
||||
private long timestamp;
|
||||
|
||||
/**
|
||||
* Creates a new soft reference that refers to the given object. The new
|
||||
* reference is not registered with any queue.
|
||||
*
|
||||
* @param referent object the new soft reference will refer to
|
||||
*/
|
||||
public SoftReference(T referent) {
|
||||
super(referent);
|
||||
this.timestamp = clock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new soft reference that refers to the given object and is
|
||||
* registered with the given queue.
|
||||
*
|
||||
* @param referent object the new soft reference will refer to
|
||||
* @param q the queue with which the reference is to be registered,
|
||||
* or <tt>null</tt> if registration is not required
|
||||
*
|
||||
*/
|
||||
public SoftReference(T referent, ReferenceQueue<? super T> q) {
|
||||
super(referent, q);
|
||||
this.timestamp = clock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this reference object's referent. If this reference object has
|
||||
* been cleared, either by the program or by the garbage collector, then
|
||||
* this method returns <code>null</code>.
|
||||
*
|
||||
* @return The object to which this reference refers, or
|
||||
* <code>null</code> if this reference object has been cleared
|
||||
*/
|
||||
public T get() {
|
||||
T o = super.get();
|
||||
if (o != null && this.timestamp != clock)
|
||||
this.timestamp = clock;
|
||||
return o;
|
||||
}
|
||||
|
||||
}
|
||||
72
jdkSrc/jdk8/java/lang/ref/WeakReference.java
Normal file
72
jdkSrc/jdk8/java/lang/ref/WeakReference.java
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package java.lang.ref;
|
||||
|
||||
|
||||
/**
|
||||
* Weak reference objects, which do not prevent their referents from being
|
||||
* made finalizable, finalized, and then reclaimed. Weak references are most
|
||||
* often used to implement canonicalizing mappings.
|
||||
*
|
||||
* <p> Suppose that the garbage collector determines at a certain point in time
|
||||
* that an object is <a href="package-summary.html#reachability">weakly
|
||||
* reachable</a>. At that time it will atomically clear all weak references to
|
||||
* that object and all weak references to any other weakly-reachable objects
|
||||
* from which that object is reachable through a chain of strong and soft
|
||||
* references. At the same time it will declare all of the formerly
|
||||
* weakly-reachable objects to be finalizable. At the same time or at some
|
||||
* later time it will enqueue those newly-cleared weak references that are
|
||||
* registered with reference queues.
|
||||
*
|
||||
* @author Mark Reinhold
|
||||
* @since 1.2
|
||||
*/
|
||||
|
||||
public class WeakReference<T> extends Reference<T> {
|
||||
|
||||
/**
|
||||
* Creates a new weak reference that refers to the given object. The new
|
||||
* reference is not registered with any queue.
|
||||
*
|
||||
* @param referent object the new weak reference will refer to
|
||||
*/
|
||||
public WeakReference(T referent) {
|
||||
super(referent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new weak reference that refers to the given object and is
|
||||
* registered with the given queue.
|
||||
*
|
||||
* @param referent object the new weak reference will refer to
|
||||
* @param q the queue with which the reference is to be registered,
|
||||
* or <tt>null</tt> if registration is not required
|
||||
*/
|
||||
public WeakReference(T referent, ReferenceQueue<? super T> q) {
|
||||
super(referent, q);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user