Использование ReferenceQueue Java

Do SoftReference и WeakReference действительно помогает только при создании в качестве переменных экземпляра? Есть ли какая-либо польза от их использования в области метода?

другая большая часть -ReferenceQueue. Помимо возможности отслеживать, какие ссылки определяются мусором, can 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 или что-то)

это реалистичный эффект? Или это пустая трата кода?

4 ответов


одна общая идиома со ссылочными очередями-например, подкласс 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 при осуществлении weakKeys выбрано использует этот подход.


если объект имеет только WeakReferenceS (или никаких ссылок!) к нему, это может быть мусор, собранный всякий раз, когда Java нужно сделать больше места в памяти. Итак, вы используете WeakReferences всякий раз, когда вы хотите, чтобы объект оставался в памяти, но вам не нужно, чтобы он оставался так плохо (например, если Java нужно собрать мусор, нет проблем, вы можете получить его обратно как-то и в то же время Java имеет лучшую производительность)

запрос a WeakReference позволяет выполнить итерацию ReferenceQueue и определить какие ссылки были собраны, а какие нет. Это все - так что делайте это, только если вам нужно это знать.

подробнее: http://weblogs.java.net/blog/2006/05/04/understanding-weak-references


одна общая вещь, котор нужно сделать создать карты мягких ссылок.

Map<String, SoftReference<BigThing>> cache = new HashMap<>();
Set<String> thingsIAmCurrentlyGetting = new HashSet<String>();
Object mutex = new Object();

BigThing getThing(String key) {
  synchronized(mutex) {
    while(thingsIAmCurrentlyGetting.contains(key)) {
      mutex.wait();
    }
    SoftReference<BigThing> ref = cache.get(key);
    BigThing bigThing = ref == null ? null : ref.get();
    if(bigThing != null) return bigThing;
    thingsIAmCurrentlyGetting.add(key);
  }

  BigThing bigThing = getBigThing(key); // this may take a while to run.

  synchronized(mutex) {
    cache.put(key, bigThing);
    thingsIAmCurrentlyGetting.remove(key);
    mutex.notifyAll();
  }

  return bigThing;
}

Я показываю здесь свою старую школу - новые пакеты java, вероятно, имеют гораздо более аккуратные способы сделать это.


Не уверен, что здесь вопрос, но:

1) soft ref попробуйте сохранить ссылку, пока jvm действительно не понадобится память. Отлично подходит для тайников, esp LRU. Посмотрите на многие примеры в гуаве.

2) слабый ref не пытайтесь предотвратить gc, чтобы освободить объект вообще. Они используются, если вы хотите знать, используется ли этот объект где-то еще. Например, они используются для хранения информации о потоках и классах, так что когда поток или класс больше не используются, мы можем отбросьте metainfo, связанный с этим.

3) phantom ref похожи на слабые, но не позволяют ссылаться на фактический объект. Таким образом, вы можете быть уверены, что передача Фантома не может возобновить фактический объект (это риск со слабым ref). Также phantom ref блокируют объект, который будет собран, пока вы не очистите ref.

ReferenceQueue: вы не enque вещи там. gc сделает для вас. Они позволяют узнать, когда некоторые ссылки освобождаются, без приходится проверять их одного за другим.