匿名监听器是否与弱引用不兼容?

Ced*_*tin 17 java garbage-collection callback anonymous-methods

我正在读这个被问到的问题:避免回调中的内存泄漏?

我很困惑,直到有人回答以下问题:

"这种方法的问题是你不能有一个只在集合中引用的监听器,因为它会随机消失(在下一个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)
    }

}
Run Code Online (Sandbox Code Playgroud)

我使用CopyOnWriteArrayList跟踪侦听器(上面的默认Observable显然使用了一个旧的Vector,但它只是一个示例来说明我通常如何创建一个匿名类来用作侦听器).

作为一个额外的问题:如果可观察对象使用WeakHashMap,那么对匿名侦听器的引用何时才符合GC的条件?当主要方法退出时?一旦obs.addObserver调用结束了吗?

我对于保存/存储/忽略对GC的匿名类实例的引用的位置/方式/时间有点困惑.

显然,如果我保持一个正常参考它没有资格GC,但什么时候是WeakHashMap中,当不正是听众成为符合使用GC?

Joo*_*gen 6

是的,你是对的,一个可监听的类,用弱引用来维护监听器(WeakHashMap也是如此)需要它们的独立持久性.可用于侦听器具有子级和父级的侦听器层次结构.

对于非WeakReference用法,必须调用显式的removeListener.除非侦听器对象可以与可听对象一样长.在大多数用例中都很好,而匿名类也可以.

对于匿名类实例,只有在访问类主体外的最终对象时才会发生泄漏(GC预防).

注意:WeakHashMap ia对其自己的Map.Entry子类使用弱引用.这有时可能令人难以置信.


Pet*_*rey 3

如果一个对象只是 WeakHashMap 的一个键,那么它就符合条件并且可能在下一次 GC 时被清理。

使用弱引用集合的整个想法是隐式删除不再引用的侦听器。(这避免了潜在的内存泄漏)问题是监听器可能会在“随机”时间点被过早删除。