SoftReferenceWeakReference是否仅在创建为实例变量时才真正起作用?在方法范围内使用它们有什么好处?

另一个重要部分是ReferenceQueue。除了能够跟踪确定垃圾的引用之外,Reference.enqueue()是否可以用于强制注册对象以进行垃圾回收?

例如,是否值得创建一个方法,该方法在对象中占用一些繁重的内存资源(由强引用保存),并创建引用以将它们排入队列?

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或其他东西)

这有现实效果吗?还是这只是浪费代码?

最佳答案

引用队列的一种常见用法是子类WeakReference可以附加清理所需的信息,然后轮询ReferenceQueue以获得清理任务。

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().
}

例如,当CacheBuilder选择 Guava 的weakKeys实现内部uses这种方法。

关于java - 使用Java的ReferenceQueue,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14450538/

10-12 01:15