下面列出了java.lang.ref.Reference#clear ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Repeatedly dequeues references from the queue and invokes
* {@link FinalizableReference#finalizeReferent()} on them until the queue is empty. This method
* is a no-op if the background thread was created successfully.
*/
void cleanUp() {
if (threadStarted) {
return;
}
Reference<?> reference;
while ((reference = queue.poll()) != null) {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
try {
((FinalizableReference) reference).finalizeReferent();
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
}
}
/**
* Repeatedly dequeues references from the queue and invokes
* {@link FinalizableReference#finalizeReferent()} on them until the queue is empty. This method
* is a no-op if the background thread was created successfully.
*/
void cleanUp() {
if (threadStarted) {
return;
}
Reference<?> reference;
while ((reference = queue.poll()) != null) {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
try {
((FinalizableReference) reference).finalizeReferent();
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
}
}
/**
* Repeatedly dequeues references from the queue and invokes
* {@link FinalizableReference#finalizeReferent()} on them until the queue is empty. This method
* is a no-op if the background thread was created successfully.
*/
void cleanUp() {
if (threadStarted) {
return;
}
Reference<?> reference;
while ((reference = queue.poll()) != null) {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
try {
((FinalizableReference) reference).finalizeReferent();
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
}
}
/**
* Repeatedly dequeues references from the queue and invokes
* {@link FinalizableReference#finalizeReferent()} on them until the queue is empty. This method
* is a no-op if the background thread was created successfully.
*/
void cleanUp() {
if (threadStarted) {
return;
}
Reference<?> reference;
while ((reference = queue.poll()) != null) {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
try {
((FinalizableReference) reference).finalizeReferent();
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
}
}
/**
* Repeatedly dequeues references from the queue and invokes
* {@link FinalizableReference#finalizeReferent()} on them until the queue is empty. This method
* is a no-op if the background thread was created successfully.
*/
void cleanUp() {
if (threadStarted) {
return;
}
Reference<?> reference;
while ((reference = queue.poll()) != null) {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
try {
((FinalizableReference) reference).finalizeReferent();
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
}
}
/**
* Repeatedly dequeues references from the queue and invokes
* {@link FinalizableReference#finalizeReferent()} on them until the queue is empty. This method
* is a no-op if the background thread was created successfully.
*/
void cleanUp() {
if (threadStarted) {
return;
}
Reference<?> reference;
while ((reference = queue.poll()) != null) {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
try {
((FinalizableReference) reference).finalizeReferent();
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
}
}
@Override
@SuppressWarnings("unchecked")
public T remove(final int index) {
Object oldValue;
Reference<T> ref;
do {
this.assertRange(index, false);
ref = (Reference<T>) this.data[index];
oldValue = ref.get();
} while (oldValue == null);
ref.clear();
System.arraycopy(this.data, index + 1, this.data, index, this.size - index - 1);
this.data[this.size - 1] = null;
this.size -= 1;
this.modCount += 1;
return (T) WeakArrayList.unmaskNull(oldValue);
}
/********** test core **********/
protected void runTests() throws Exception {
targetClass = startToMain("ConstantPoolGCTarg").location().declaringType();
if (vm().canGetConstantPool()) {
byte[] cpbytes = targetClass.constantPool();
// imitate SoftReference cleared
Field constantPoolBytesRef = ReferenceTypeImpl.class.getDeclaredField("constantPoolBytesRef");
constantPoolBytesRef.setAccessible(true);
Reference softRef = (Reference) constantPoolBytesRef.get(targetClass);
softRef.clear();
byte[] cpbytes2 = targetClass.constantPool();
if (!Arrays.equals(cpbytes, cpbytes2)) {
failure("Consequent constantPool results vary, first was : " + cpbytes + ", now: " + cpbytes2);
};
} else {
System.out.println("can get constant pool version not supported");
}
/*
* resume until end
*/
listenUntilVMDisconnect();
/*
* deal with results of test
* if anything has called failure("foo") testFailed will be true
*/
if (!testFailed) {
println("ConstantPoolInfoGC: passed");
} else {
throw new Exception("ConstantPoolInfoGC: failed");
}
}
/********** test core **********/
protected void runTests() throws Exception {
targetClass = startToMain("ConstantPoolGCTarg").location().declaringType();
if (vm().canGetConstantPool()) {
byte[] cpbytes = targetClass.constantPool();
// imitate SoftReference cleared
Field constantPoolBytesRef = ReferenceTypeImpl.class.getDeclaredField("constantPoolBytesRef");
constantPoolBytesRef.setAccessible(true);
Reference softRef = (Reference) constantPoolBytesRef.get(targetClass);
softRef.clear();
byte[] cpbytes2 = targetClass.constantPool();
if (!Arrays.equals(cpbytes, cpbytes2)) {
failure("Consequent constantPool results vary, first was : " + cpbytes + ", now: " + cpbytes2);
};
} else {
System.out.println("can get constant pool version not supported");
}
/*
* resume until end
*/
listenUntilVMDisconnect();
/*
* deal with results of test
* if anything has called failure("foo") testFailed will be true
*/
if (!testFailed) {
println("ConstantPoolInfoGC: passed");
} else {
throw new Exception("ConstantPoolInfoGC: failed");
}
}
/**
* Cleans up a single reference. Catches and logs all throwables.
*
* @return true if the caller should continue, false if the associated FinalizableReferenceQueue
* is no longer referenced.
*/
private boolean cleanUp(Reference<?> reference) {
Method finalizeReferentMethod = getFinalizeReferentMethod();
if (finalizeReferentMethod == null) {
return false;
}
do {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
if (reference == frqReference) {
/*
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
return false;
}
try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
*/
} while ((reference = queue.poll()) != null);
return true;
}
/**
* Cleans up a single reference. Catches and logs all throwables.
*
* @return true if the caller should continue, false if the associated FinalizableReferenceQueue
* is no longer referenced.
*/
private boolean cleanUp(Reference<?> reference) {
Method finalizeReferentMethod = getFinalizeReferentMethod();
if (finalizeReferentMethod == null) {
return false;
}
do {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
if (reference == frqReference) {
/*
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
return false;
}
try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
*/
} while ((reference = queue.poll()) != null);
return true;
}
/**
* Cleans up a single reference. Catches and logs all throwables.
*
* @return true if the caller should continue, false if the associated FinalizableReferenceQueue
* is no longer referenced.
*/
private boolean cleanUp(Reference<?> reference) {
Method finalizeReferentMethod = getFinalizeReferentMethod();
if (finalizeReferentMethod == null) {
return false;
}
do {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
if (reference == frqReference) {
/*
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
return false;
}
try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
*/
} while ((reference = queue.poll()) != null);
return true;
}
/**
* Invoked in a background thread after a value has been set in the map.
* This method computes a cost estimation of the new value. If the total cost is greater
* than the cost limit, then oldest strong references are replaced by weak references.
*/
final void adjustReferences(final K key, final V value) {
int cost = (value != null) ? cost(value) : 0;
synchronized (costs) {
final Integer old = costs.put(key, cost);
if (old != null) {
cost -= old;
}
if ((totalCost += cost) > costLimit) {
final Iterator<Map.Entry<K,Integer>> it = costs.entrySet().iterator();
while (it.hasNext()) {
/*
* Converts the current entry from strong reference to weak/soft reference.
* We perform this conversion even if the entry is for the value just added
* to the cache, if it happen that the cost is higher than the maximal one.
* That entry should not be garbage collected too early anyway because the
* caller should still have a strong reference to the value he just created.
*/
final Map.Entry<K,Integer> entry = it.next();
final K oldKey = entry.getKey();
final Object oldValue = map.get(oldKey);
if (oldValue != null && !isReservedType(oldValue)) {
@SuppressWarnings("unchecked")
final Reference<V> ref = soft ? new Soft<>(map, oldKey, (V) oldValue)
: new Weak<>(map, oldKey, (V) oldValue);
if (!map.replace(oldKey, oldValue, ref)) {
ref.clear(); // Prevents the reference to be enqueued.
}
}
it.remove();
if ((totalCost -= entry.getValue()) <= costLimit) {
break;
}
}
}
}
}
/**
* Cleans up a single reference. Catches and logs all throwables.
*
* @return true if the caller should continue, false if the associated FinalizableReferenceQueue
* is no longer referenced.
*/
private boolean cleanUp(Reference<?> reference) {
Method finalizeReferentMethod = getFinalizeReferentMethod();
if (finalizeReferentMethod == null) {
return false;
}
do {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
if (reference == frqReference) {
/*
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
return false;
}
try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
*/
} while ((reference = queue.poll()) != null);
return true;
}
/**
* Cleans up a single reference. Catches and logs all throwables.
*
* @return true if the caller should continue, false if the associated FinalizableReferenceQueue
* is no longer referenced.
*/
private boolean cleanUp(Reference<?> reference) {
Method finalizeReferentMethod = getFinalizeReferentMethod();
if (finalizeReferentMethod == null) {
return false;
}
do {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();
if (reference == frqReference) {
/*
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
return false;
}
try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
*/
} while ((reference = queue.poll()) != null);
return true;
}
/** Uses the parent's remove method which is blocking until a cleared
* reference is added to the queue.
* Calls the overwritten clear method of the associated reference which
* will remove the key from the cache.
* {@inheritDoc} */
@Override
public void run() {
for (;;) try {
Reference<? extends T> ref = super.remove();
if (ref != null) ref.clear();
} catch (InterruptedException e) { /* ignore try again */ System.out.println(e+" ooops");}
}
@SuppressWarnings("unchecked")
public int expurge() {
int j;
while (this.queue.poll() != null) {
this.enquedElement = true;
}
if (this.enquedElement) {
j = 0;
for (int i = 0; i < this.size; ++i) {
Reference<T> ref = (Reference<T>) this.data[i];
if (ref == null || ref.isEnqueued() || ref.get() == null) {
if (ref != null) {
ref.clear();
}
this.data[i] = null;
} else {
if (i != j) {
this.data[j] = this.data[i];
this.data[i] = null;
}
++j;
}
}
this.enquedElement = false;
} else {
j = this.size;
}
while (this.queue.poll() != null) {
this.enquedElement = true;
}
this.size = j;
return this.size;
}
@Override
@SuppressWarnings("unchecked")
public T set(final int index, final T element) {
Object oldValue;
Reference<T> ref;
do {
this.assertRange(index, false);
ref = (Reference<T>) this.data[index];
oldValue = ref.get();
} while (oldValue == null);
ref.clear();
this.data[index] = this.createRef(element);
this.modCount += 1;
return (T) WeakArrayList.unmaskNull(oldValue);
}
/**
* Cleans up a single reference. Catches and logs all throwables.
*/
private void cleanUp(Reference<?> reference) throws ShutDown {
Method finalizeReferentMethod = getFinalizeReferentMethod();
do {
/*
* This is for the benefit of phantom references. Weak and soft
* references will have already been cleared by this point.
*/
reference.clear();
if (reference == frqReference) {
/*
* The client no longer has a reference to the
* FinalizableReferenceQueue. We can stop.
*/
throw new ShutDown();
}
try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
/*
* Loop as long as we have references available so as not to waste
* CPU looking up the Method over and over again.
*/
} while ((reference = queue.poll()) != null);
}
@Override
public Object put(Object key, Object value) {
diddleReferenceQueue();
Reference oldRef = (Reference) keyToRefMap.put(key, new KeyedWeakReference(key, value, queue));
if (oldRef != null) {
Object oldRefVal = oldRef.get();
oldRef.clear();
return oldRefVal;
} else {
return null;
}
}