下面列出了怎么用java.lang.ref.Reference的API类实例代码及写法,或者点击链接到github查看源代码。
public void testIssuingFileObject() throws IOException {
FileObjectFactory fbs = FileObjectFactory.getInstance(getWorkDir());
assertEquals("One file object exists?", 1, fbs.getSize());
FileObject workDir = FileUtil.toFileObject(getWorkDir());
assertNotNull(workDir);
//root + workdir
assertEquals(2, fbs.getSize());
assertEquals(2, fbs.getSize());
Reference<FileObject> rf = new WeakReference<>(workDir.getParent());
assertGC("", rf);
assertNull(((BaseFileObj)workDir).getExistingParent());
assertEquals(2, fbs.getSize());
fbs.getRoot().getFileObject(workDir.getPath());
assertEquals(2, fbs.getSize());
rf = new WeakReference<>(workDir.getParent());
assertGC("", rf);
assertNull(((BaseFileObj)workDir).getExistingParent());
assertEquals(2, fbs.getSize());
}
public void attach(Action action) {
Reference<Action> d = delegate;
if ((d == null) || (d.get() == action)) {
return;
}
Action prev = d.get();
// reattaches to different action
if (prev != null) {
prev.removePropertyChangeListener(this);
}
this.delegate = new WeakReference<Action>(action);
action.addPropertyChangeListener(this);
}
/**
* Prints information about this {@link NDManager} and all sub-managers to the console.
*
* @param level the level of this {@link NDManager} in the hierarchy
*/
public void debugDump(int level) {
StringBuilder sb = new StringBuilder(100);
for (int i = 0; i < level; ++i) {
sb.append(" ");
}
sb.append("\\--- NDManager(")
.append(uid.substring(24))
.append(") resource count: ")
.append(resources.size());
System.out.println(sb.toString()); // NOPMD
for (Reference<AutoCloseable> ref : resources.values()) {
AutoCloseable c = ref.get();
if (c instanceof BaseNDManager) {
((BaseNDManager) c).debugDump(level + 1);
}
}
}
public static Reference<FontStrike> getStrikeRef(FontStrike strike, boolean weak) {
/* Some strikes may have no disposer as there's nothing
* for them to free, as they allocated no native resource
* eg, if they did not allocate resources because of a problem,
* or they never hold native resources. So they create no disposer.
* But any strike that reaches here that has a null disposer is
* a potential memory leak.
*/
if (strike.disposer == null) {
if (weak) {
return new WeakReference<>(strike);
} else {
return new SoftReference<>(strike);
}
}
if (weak) {
return new WeakDisposerRef(strike);
} else {
return new SoftDisposerRef(strike);
}
}
/**
* Returns a <I>Channel</I> that generates connections to the
* endpoint <I>ep</I>. A Channel is an object that creates and
* manages connections of a particular type to some particular
* address space.
* @param ep the endpoint to which connections will be generated.
* @return the channel or null if the transport cannot
* generate connections to this endpoint
*/
public TCPChannel getChannel(Endpoint ep) {
TCPChannel ch = null;
if (ep instanceof TCPEndpoint) {
synchronized (channelTable) {
Reference<TCPChannel> ref = channelTable.get(ep);
if (ref != null) {
ch = ref.get();
}
if (ch == null) {
TCPEndpoint tcpEndpoint = (TCPEndpoint) ep;
ch = new TCPChannel(this, tcpEndpoint);
channelTable.put(tcpEndpoint,
new WeakReference<TCPChannel>(ch));
}
}
}
return ch;
}
@Override
public FaweChunk getFaweChunk(int cx, int cz) {
if (cx == lastX && cz == lastZ) {
return lastWrappedChunk;
}
long pair = MathMan.pairInt(cx, cz);
Reference<FaweChunk> chunkReference = this.blocks.get(pair);
FaweChunk chunk;
if (chunkReference == null || (chunk = chunkReference.get()) == null) {
chunk = this.getNewFaweChunk(cx, cz);
Reference<FaweChunk> previous = this.blocks.put(pair, new SoftReference(chunk));
if (previous != null) {
FaweChunk tmp = previous.get();
if (tmp != null) {
chunk = tmp;
this.blocks.put(pair, previous);
}
}
}
return chunk;
}
synchronized void deregisterFontAndClearStrikeCache() {
SunFontManager fm = SunFontManager.getInstance();
fm.deRegisterBadFont(this);
for (Reference strikeRef : strikeCache.values()) {
if (strikeRef != null) {
/* NB we know these are all FileFontStrike instances
* because the cache is on this FileFont
*/
FileFontStrike strike = (FileFontStrike)strikeRef.get();
if (strike != null && strike.pScalerContext != 0L) {
scaler.invalidateScalerContext(strike.pScalerContext);
}
}
}
if (scaler != null) {
scaler.disposeScaler();
}
scaler = FontScaler.getNullScaler();
}
public void testMemoryLeak() throws Exception {
final AtomicInteger count = new AtomicInteger();
Action singleton = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
count.incrementAndGet();
}
};
Object heavy = new Object();
AlwaysEnabledAction always = AlwaysEnabledAction.create(
Collections.singletonMap("delegate", singleton)
);
Action clone = always.createContextAwareInstance(Lookups.singleton(heavy));
clone.actionPerformed(null);
assertEquals(1, count.get());
Reference<?> r = new WeakReference<Object>(heavy);
clone = null;
heavy = null;
assertGC("should not leak context", r, Collections.singleton(singleton));
}
@SuppressWarnings("unchecked")
public static synchronized <T extends TokenId> WrapTokenIdCache<T> get(Language<T> language) {
int lid = id(language);
if (cacheRefs == null || lid >= cacheRefs.length) {
Reference<WrapTokenIdCache<?>>[] n = (Reference<WrapTokenIdCache<?>>[])
new Reference[lid + 1];
if (cacheRefs != null) {
System.arraycopy(cacheRefs, 0, n, 0, cacheRefs.length);
}
cacheRefs = n;
}
Reference<WrapTokenIdCache<?>> cacheRef = cacheRefs[lid];
WrapTokenIdCache<T> cache;
if (cacheRef == null || (cache = (WrapTokenIdCache<T>) cacheRef.get()) == null) {
cache = new WrapTokenIdCache<T>(language);
cacheRefs[lid] = new WeakReference<WrapTokenIdCache<?>>(cache);
}
return cache;
}
/**
* Verify that the given AccessControlContext has permission to
* accept this connection.
*/
void checkAcceptPermission(SecurityManager sm,
AccessControlContext acc)
{
/*
* Note: no need to synchronize on cache-related fields, since this
* method only gets called from the ConnectionHandler's thread.
*/
if (sm != cacheSecurityManager) {
okContext = null;
authCache = new WeakHashMap<AccessControlContext,
Reference<AccessControlContext>>();
cacheSecurityManager = sm;
}
if (acc.equals(okContext) || authCache.containsKey(acc)) {
return;
}
InetAddress addr = socket.getInetAddress();
String host = (addr != null) ? addr.getHostAddress() : "*";
sm.checkAccept(host, socket.getPort());
authCache.put(acc, new SoftReference<AccessControlContext>(acc));
okContext = acc;
}
public static void main(String[] args) {
int[] ids = new int[]{
CS_sRGB, CS_CIEXYZ, CS_GRAY, CS_LINEAR_RGB, CS_PYCC
};
for (int id : ids) {
ICC_Profile p = getCopyOf(id);
}
while (!v.isEmpty()) {
System.gc();
System.out.println(".");
try {
Thread.sleep(500);
} catch (InterruptedException e) {};
final Reference<? extends ICC_Profile> ref = queue.poll();
System.out.println("Got reference: " + ref);
v.remove(ref);
}
System.out.println("Test PASSED.");
}
public static Reference getStrikeRef(FontStrike strike, boolean weak) {
/* Some strikes may have no disposer as there's nothing
* for them to free, as they allocated no native resource
* eg, if they did not allocate resources because of a problem,
* or they never hold native resources. So they create no disposer.
* But any strike that reaches here that has a null disposer is
* a potential memory leak.
*/
if (strike.disposer == null) {
if (weak) {
return new WeakReference(strike);
} else {
return new SoftReference(strike);
}
}
if (weak) {
return new WeakDisposerRef(strike);
} else {
return new SoftDisposerRef(strike);
}
}
/**
* Get language path corresponding to the suffix language path embedded
* in this path.
*
* @param suffix non-null suffix to be added to this path.
* @return non-null language path consisting of this path with the
* suffix added to the end.
*/
public LanguagePath embedded(LanguagePath suffix) {
if (suffix == null) {
throw new IllegalArgumentException("suffix cannot be null");
}
// Attempt to retrieve from the cache first
synchronized (languages) {
initLanguage2path();
Reference<LanguagePath> lpRef = language2path.get(suffix);
LanguagePath lp;
if (lpRef == null || (lp = lpRef.get()) == null) {
// Construct the LanguagePath
lp = this;
for (int i = 0; i < suffix.size(); i++) {
lp = lp.embedded(suffix.language(i));
}
language2path.put(suffix, new SoftReference<LanguagePath>(lp));
}
return lp;
}
}
/**
* Purges the specified reference
* @param ref the reference to purge
* @return true or false
*/
boolean purge(Reference ref) {
boolean r = (parent.keyType > HARD) && (key == ref);
r = r || ((parent.valueType > HARD) && (value == ref));
if (r) {
if (parent.keyType > HARD) {
((Reference)key).clear();
}
if (parent.valueType > HARD) {
((Reference)value).clear();
} else if (parent.purgeValues) {
value = null;
}
}
return r;
}
@Override
public void virtualize(VirtualizerTool tool) {
/*
* Reference objects can escape into their ReferenceQueue at any safepoint, therefore
* they're excluded from escape analysis.
*/
if (!tool.getMetaAccessProvider().lookupJavaType(Reference.class).isAssignableFrom(instanceClass)) {
VirtualInstanceNode virtualObject = createVirtualInstanceNode(true);
ResolvedJavaField[] fields = virtualObject.getFields();
ValueNode[] state = new ValueNode[fields.length];
for (int i = 0; i < state.length; i++) {
state[i] = defaultFieldValue(fields[i]);
}
tool.createVirtualObject(virtualObject, state, Collections.<MonitorIdNode> emptyList(), false);
tool.replaceWithVirtual(virtualObject);
}
}
@Override
public synchronized WhiteListImplementation getWhiteList(final FileObject file) {
final Reference<WhiteListImplementation> ref = canonicalCache.get(file);
WhiteListImplementation wl = ref == null ? null : ref.get();
if (wl != null) {
return wl;
}
final Lookup.Result<WhiteListQueryImplementation> lr = lkp.lookupResult(WhiteListQueryImplementation.class);
boolean empty = true;
for (WhiteListQueryImplementation impl : lr.allInstances()) {
WhiteListImplementation i = impl.getWhiteList(file);
if (i != null) {
empty = false;
break;
}
}
if (empty) {
return null;
}
wl = new WhiteListImplementationMerged(lr,file);
canonicalCache.put(file,new WeakReference<WhiteListImplementation>(wl));
return wl;
}
/**
* Closes all cached connections in every channel subordinated to this
* transport. Currently, this only closes outgoing connections.
*/
public void shedConnectionCaches() {
List<TCPChannel> channels;
synchronized (channelTable) {
channels = new ArrayList<TCPChannel>(channelTable.values().size());
for (Reference<TCPChannel> ref : channelTable.values()) {
TCPChannel ch = ref.get();
if (ch != null) {
channels.add(ch);
}
}
}
for (TCPChannel channel : channels) {
channel.shedCache();
}
}
/**
* Test that releasing the reference to the Cleaner service allows it to be
* be freed.
*/
@Test
void testCleanerTermination() {
ReferenceQueue<Object> queue = new ReferenceQueue<>();
Cleaner service = Cleaner.create();
PhantomReference<Object> ref = new PhantomReference<>(service, queue);
System.gc();
// Clear the Reference to the cleaning service and force a gc.
service = null;
System.gc();
try {
Reference<?> r = queue.remove(1000L);
Assert.assertNotNull(r, "queue.remove timeout,");
Assert.assertEquals(r, ref, "Wrong Reference dequeued");
} catch (InterruptedException ie) {
System.out.printf("queue.remove Interrupted%n");
}
}
public void testReadOnlyLocalRepositoryFile() throws Exception {
File repo = EmbedderFactory.getProjectEmbedder().getLocalRepositoryFile();
File f = TestFileUtils.writeFile(new File(repo, "ant/ant/1.5.1/ant-1.5.1.jar.sha1"), "a50e3e050a6e78e0656edc183435b9773f53ce78");
FileObject rw = FileUtil.toFileObject(f);
FileObject ro = NodeUtils.readOnlyLocalRepositoryFile(rw);
assertNotSame(rw, ro);
assertFalse(ro.canWrite());
assertNotNull(DataObject.find(ro).getLookup().lookup(OpenCookie.class));
f = TestFileUtils.writeFile(new File(repo, "ant/ant/1.5.1/ant-1.5.1.pom.sha1"), "0ffdb41f140a621beeec4dc81b3d3ecaee085d28");
rw = FileUtil.toFileObject(f);
ro = NodeUtils.readOnlyLocalRepositoryFile(rw);
assertNotSame(rw, ro);
assertFalse(ro.canWrite());
assertNotNull(DataObject.find(ro).getLookup().lookup(OpenCookie.class));
assertSame(ro, NodeUtils.readOnlyLocalRepositoryFile(rw));
FileObject skip = FileUtil.toFileObject(new File(repo, "ant/ant/1.5.1"));
assertNotNull(skip);
assertSame(skip, NodeUtils.readOnlyLocalRepositoryFile(skip));
File stuff = TestFileUtils.writeFile(new File(getWorkDir(), "stuff"), "stuff");
skip = FileUtil.toFileObject(stuff);
assertNotNull(skip);
assertSame(skip, NodeUtils.readOnlyLocalRepositoryFile(skip));
Reference<?> r = new WeakReference<Object>(ro.getFileSystem());
ro = null;
assertGC("can collect FS", r);
}
public static Reference getStrikeRef(FontStrike strike, boolean weak) {
/* Some strikes may have no disposer as there's nothing
* for them to free, as they allocated no native resource
* eg, if they did not allocate resources because of a problem,
* or they never hold native resources. So they create no disposer.
* But any strike that reaches here that has a null disposer is
* a potential memory leak.
*/
if (strike.disposer == null) {
if (weak) {
return new WeakReference(strike);
} else {
return new SoftReference(strike);
}
}
if (weak) {
return new WeakDisposerRef(strike);
} else {
return new SoftDisposerRef(strike);
}
}
private void purge(Reference ref) {
// The hashCode of the reference is the hashCode of the
// mapping key, even if the reference refers to the
// mapping value...
int hash = ref.hashCode();
int index = indexFor(hash);
Entry previous = null;
Entry entry = table[index];
while (entry != null) {
if (entry.purge(ref)) {
if (previous == null) table[index] = entry.next;
else previous.next = entry.next;
this.size--;
return;
}
previous = entry;
entry = entry.next;
}
}
/**
* Finds a stored type or returns {@code null} if no type was stored.
*
* @param classLoader The class loader for which this type is stored.
* @param key The key for the type in question.
* @return The stored type or {@code null} if no type was stored.
*/
@SuppressFBWarnings(value = "GC_UNRELATED_TYPES", justification = "Cross-comparison is intended")
public Class<?> find(ClassLoader classLoader, T key) {
ConcurrentMap<T, Reference<Class<?>>> storage = cache.get(new LookupKey(classLoader));
if (storage == null) {
return NOT_FOUND;
} else {
Reference<Class<?>> reference = storage.get(key);
if (reference == null) {
return NOT_FOUND;
} else {
return reference.get();
}
}
}
@SuppressWarnings("unchecked")
K key() {
if (keyRef instanceof KeyReference)
return ((Reference<K>)keyRef).get();
return (K) keyRef;
}
/**
* Returns a value to which the specified {@code key} is mapped,
* or {@code null} if this map contains no mapping for the {@code key}.
*
* @param key the key whose associated value is returned
* @return a value to which the specified {@code key} is mapped
*/
public V get(K key) {
Reference<V> reference = this.map.get(key);
if (reference == null) {
return null;
}
V value = reference.get();
if (value == null) {
this.map.remove(key);
}
return value;
}
/**
* Return the method from the cache, if present.
*
* @param md The method descriptor
* @return The cached method
*/
private static Method getCachedMethod(final MethodDescriptor md) {
if (CACHE_METHODS) {
final Reference<Method> methodRef = cache.get(md);
if (methodRef != null) {
return methodRef.get();
}
}
return null;
}
@Override
public Reference<FaweChunk> put(long key, Reference<FaweChunk> value) {
if (parent.getProgressTask() != null) {
try {
parent.getProgressTask().run(FaweQueue.ProgressType.QUEUE, size());
} catch (Throwable e) {
e.printStackTrace();
}
}
synchronized (this) {
return super.put(key, value);
}
}
public static final void main(String[] args) throws Exception {
System.err.println("\n Regression test for bug 6232010\n");
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
ClassLoader loader = new URLClassLoader(((URLClassLoader) systemLoader).getURLs(),
systemLoader.getParent());
Class<? extends ObjectOutputStream> cl =
Class.forName(SubclassOfOOS.class.getName(), false,
loader).asSubclass(ObjectOutputStream.class);
Constructor<? extends ObjectOutputStream> cons =
cl.getConstructor(OutputStream.class);
OutputStream os = new ByteArrayOutputStream();
ObjectOutputStream obj = cons.newInstance(os);
final ReferenceQueue<Class<?>> queue = new ReferenceQueue<Class<?>>();
WeakReference<Class<?>> ref = new WeakReference<Class<?>>(cl, queue);
cl = null;
obj = null;
loader = null;
cons = null;
systemLoader = null;
System.err.println("\nStart Garbage Collection right now");
System.gc();
Reference<? extends Class<?>> dequeued = queue.remove(TIMEOUT);
if (dequeued == ref) {
System.err.println("\nTEST PASSED");
} else {
throw new Error();
}
}
private void hardLock() throws IOException {
Collection<Reference<LockForFile>> refs = values();
for (Reference<LockForFile> reference : refs) {
if (reference != null) {
LockForFile lockForFile = reference.get();
if (lockForFile != null) {
if (!FileChangedManager.getInstance().exists(lockForFile.getLock())) {
lockForFile.hardLock();
}
}
}
}
}
public ClassHierarchy(ResourceLoader loader) {
this.loader = loader;
this.lookupCache = new HashMap<Key, String>();
this.typesCache = new WeakHashMap<TypeInfo, Reference<TypeInfo>>();
// Next will never be removed from the cache
// while there is a hard-reference
for (TypeInfo ti : SPECIAL_CLASSES) {
typesCache.put(ti, new SoftReference<TypeInfo>(ti));
}
}
void removeFromCache(FontStrikeDesc desc) {
Reference ref = strikeCache.get(desc);
if (ref != null) {
Object o = ref.get();
if (o == null) {
strikeCache.remove(desc);
}
}
}