2011-12-12 50 views
17

我读这问那刚刚问: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(默认可观察上面显然使用旧矢量但它只是一个例子来跟踪监听器显示我通常如何创建一个匿名类用作侦听器)。

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

我对有关匿名类实例的引用在何处/如何/何时被保存/存储/保存为GC有些困惑。

显然,如果我保持一个正常参考它没有资格GC,但什么时候是WeakHashMap中,什么时候正是听者的GC成为elligible?

回答

3

如果一个对象只是WeakHashMap的关键字,那么它就符合条件并可能在下一个GC中清除。

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

+1

感谢您的帮助,我明白这一点。但是我的问题确实涉及到匿名监听器:如果我在WeakHashMap中引用匿名监听器,那么是否还有另一个对该匿名监听器的引用保存在别的地方?如果没有,那么在哪个时候确实可以用于GC?在哪个电话之后? –

6

是的,你是对的,一个可监听的类保持弱引用的监听器(就像WeakHashMap一样)需要它们的独立持久性。可以用于监听器有子代和父代的监听器层次结构。

对于non-WeakReference用法,必须调用显式removeListener。除非听者对象可以像可听对象一样长。在大多数情况下,这是很好的,而且一个匿名类将会这样做。

使用匿名类实例一泄漏(GC预防)访问类身体外部的最终对象时,可能仅发生。

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