问题描述
SoftReference
和 WeakReference
真的只在作为实例变量创建时有用吗?在方法范围内使用它们有什么好处吗?
Do SoftReference
and WeakReference
really only help when created as instance variables? Is there any benefit to using them in method scope?
另一大部分是ReferenceQueue
.Reference.enqueue()
除了能够跟踪哪些引用被确定为垃圾之外,还可以用来强制注册一个对象进行垃圾回收吗?
The other big part is ReferenceQueue
. Besides being able to track which references are determined garbage, can Reference.enqueue()
be used to forcibly register an object for garbage collection?
例如,创建一个在对象中占用大量内存资源(由强引用持有)并创建引用以将它们排入队列的方法是否值得?
For example, would it be worth to create a method that takes some heavy memory resources (held by strong references) in an object and creating References to enqueue them?
Object bigObject;
public void dispose() {
ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
WeakReference<Object> ref = new WeakReference<Object>(bigObject, queue);
bigObject = null;
ref.enqueue();
}
(想象一下,在这种情况下,Object 代表一种使用大量内存的对象类型……比如 BufferedImage
或其他东西)
(Imagine that Object in this case represents an object type that uses a lot of memory... like BufferedImage
or something)
这有什么现实效果吗?或者这只是浪费代码?
Does this have any realistic effect? Or is this just a waste of code?
推荐答案
引用队列的一个常见习语是例如子类 WeakReference
附加清理所需的信息,然后轮询 ReferenceQueue
以获取清理任务.
One common idiom with reference queues is to e.g. subclass WeakReference
to attach information that's needed to clean up things, and then to poll a ReferenceQueue
to get cleanup tasks.
ReferenceQueue<Foo> fooQueue = new ReferenceQueue<Foo>();
class ReferenceWithCleanup extends WeakReference<Foo> {
Bar bar;
ReferenceWithCleanup(Foo foo, Bar bar) {
super(foo, fooQueue);
this.bar = bar;
}
public void cleanUp() {
bar.cleanUp();
}
}
public Thread cleanupThread = new Thread() {
public void run() {
while(true) {
ReferenceWithCleanup ref = (ReferenceWithCleanup)fooQueue.remove();
ref.cleanUp();
}
}
}
public void doStuff() {
cleanupThread.start();
Foo foo = new Foo();
Bar bar = new Bar();
ReferenceWithCleanup ref = new ReferenceWithCleanup(foo, bar);
... // From now on, once you release all non-weak references to foo,
// then at some indeterminate point in the future, bar.cleanUp() will
// be run. You can force it by calling ref.enqueue().
}
例如,选择weakKeys
时Guava的CacheBuilder
实现的内部结构使用这种方法.
For example, the internals of Guava's CacheBuilder
implementation when weakKeys
are selected uses this approach.
这篇关于使用 Java 的 ReferenceQueue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!