使用Java的ReferenceQueue

2024-03-12

Do SoftReference and WeakReference真的只有在创建为实例变量时才有帮助吗?在方法范围内使用它们有什么好处吗?

另一个重要部分是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();
}

(想象一下,在这种情况下,对象代表一个使用大量内存的对象类型......就像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().
}

例如,Guava 的内部结构CacheBuilder执行时weakKeys被选中uses http://google.github.io/guava/releases/19.0/api/docs/com/google/common/cache/CacheBuilder.html#weakKeys()这种方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用Java的ReferenceQueue 的相关文章

随机推荐