我正在阅读刚刚被问到的这个问题:Avoid memory leaks in callbacks?
我很困惑,直到有人回答了以下问题:
“这种方法的问题是您不能拥有仅在集合中引用的监听器,因为它会随机消失(在下一次 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 显然使用旧的 Vector 但它只是一个示例显示我通常如何创建匿名类用作监听器)。
作为奖励问题:如果可观察对象使用 WeakHashMap,那么对匿名监听器的引用何时符合 GC 的条件? main 方法何时退出? obs.addObserver 调用一结束?
对于匿名类实例的引用在何处/如何/何时保留/存储/符合 GC 条件,我有点困惑。
显然,如果我保留一个普通引用,它不符合 GC 的条件,但是当它在 WeakHashMap 中时,监听器什么时候准确地有资格进行 GC?
最佳答案
是的,你是对的,一个用弱引用维护监听器的可监听类(就像 WeakHashMap 一样)需要它们的独立持久性。可用于听众有 child 和 parent 的听众层次结构。
对于非 WeakReference 用法,必须调用显式 removeListener。除非监听器对象可能与可监听对象一样长。在大多数用例中这很好,匿名类就可以了。
对于匿名类实例,泄漏(GC 预防)可能仅在访问类主体外部的final 对象时发生。
注意:WeakHashMap i.a.对其自己的 Map.Entry 子类使用弱引用。这有时可能令人难以置信。
关于java - 匿名监听器是否与弱引用不兼容?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8475646/