1

我有以下类层次结构。出于某种原因,即使我保持对它的强烈引用,我的听众也会被垃圾收集。

class MyModule { 
   MySubModule submodule = null;

   MyModule(Channel ch) {
      submodule = new MySubModule(ch);
   }
}

class MySubModule { 
   MyListener listener = null;

   MySubModule(Channel ch) {
      listener = new MyListener();
      ch.subscribe(listener);
   }
}

class Channel { 
   Map<MyListener, Boolean> backend = new WeakHashMap<MyListener, Boolean>();
   Set<MyListener> listeners = Collections.newSetFromMap(backend);

   void subscribe(MyListener listener) {
       listeners.add(listener);
   }

   void fireListeners() {
       // listeners get garbage collected so they won't get fired
       for (MyListener listener:listeners) {
          listener.observe(someEvt);
       }
   }
}

Channel 类在 WeakHashSet 中维护一组侦听器。所以我在 MySubModule 中注册了监听器,同时在同一个类(变量监听器)中保持对它的强引用。但是,JVM 仍然会垃圾收集侦听器实例。一旦有强引用,它不应该留在 WeakHashSet 中吗?在这种情况下,我真的相信我有一个以上。有人可以告诉我我在这里做错了什么吗?

编辑:我也在上面添加了 Channel 的实现。同样在 main(...) 方法中,我有以下内容:

static void main(...) {
    Channel ch = new Channel();
    MyModule myModule = new MyModule(ch);
    // do some real stuff here.
}
4

1 回答 1

1

如果您仍然对 MyModule 有强烈的引用,MyListener 不可能被垃圾收集。

要么您没有正确设置子模块,要么您没有正确设置监听器,或者您从未将监听器添加到后端 WeakHashMap(我猜这是最可能的)。

你怎么知道监听器被垃圾回收了?您可能会检查它是否存在于后端 WeakHashMap 中。它不在那里,所以你声称它是 gc'ed。但实际上它从未添加到其中。让我知道这是否正确。

首先检查你是否真的对 Module 和 SubModule 有很强的引用。如果有,请检查 SubModule 是否具有对 MyListener 的有效引用。

于 2013-10-01T19:38:53.140 回答