Анонимные слушатели несовместимы со слабыми ссылками?

Я читал этот вопрос, который только что спросил: Избегайте утечек памяти в обратных вызовах?

И я был очень смущен, пока кто-то не ответил на следующее:

«Проблема с этим подходом заключается в том, что у вас не может быть слушателя, который упоминается только в коллекции, поскольку он случайно исчезнет (на следующем GC)»

Правильно ли я понимаю, что использование слабых ссылок, например, при хранении в WeakHashMap , несовместимо с анонимными слушателями?

Я обычно передаю слушателям вот так:

public static void main(String[] args) { final Observable obs = new SomeObservable(); obs.addObserver(new Observer() { public void update(final Observable o, final Object arg) { System.out.println("Notified"); } }); obs.notifyObservers(); ... // program continues its life here } private static final class SomeObservable extends Observable { @Override public void addObserver(final Observer o) { super.addObserver(o); setChanged(); // shouldn't be done from here (unrelated to the question) } } 

И я отслеживаю слушателей, используя CopyOnWriteArrayList (по умолчанию Observable, очевидно, использует старый вектор, но его просто пример, показывающий, как я обычно создаю анонимный class для использования в качестве слушателя).

В качестве бонусного вопроса: когда ссылка на анонимного слушателя будет иметь право на GC, если наблюдаемый субъект использует WeakHashMap? Когда основной метод выходит? Как только вызов obs.addObserver закончился?

Я немного смущен тем, где / как / когда ссылки на экземпляры анонимного classа хранятся / хранятся / доступны для GC.

Очевидно, что если я поддерживаю нормальную ссылку, он не подходит для GC, но что, когда он находится в WeakHashMap, когда именно слушатель становится понятным для GC?

Да, вы правы, слушающий class, поддерживающий слушателей со слабыми ссылками (как и WeakHashMap), требует их независимой настойчивости. Может использоваться для иерархии слушателей, где у слушателя есть дети и родитель.

Для использования не-WeakReference необходимо вызывать явный removeListener. Если объект прослушивателя не может прожить до тех пор, пока его прослушиваемый объект. В большинстве случаев использования это нормально, и анонимный class будет делать.

При использовании анонимных экземпляров classа утечка (предотrotation GC) может произойти только при доступе к конечному объекту вне тела classа.

Примечание. WeakHashMap ia использует слабые ссылки для собственного подclassа Map.Entry. Который иногда может быть совершенно ошеломляющим.

Если объект является только ключом WeakHashMap, то он имеет право и может быть очищен на следующем GC.

Вся идея использования коллекции «Слабая ссылка» заключается в том, чтобы неявно удалить прослушиватели, на которые больше не ссылаются. (Это позволяет избежать утечки памяти). Проблема заключается в том, что слушатель может быть удален преждевременно и в «случайный» момент времени.