为什么我的实例垃圾被收集了

时间:2013-10-01 19:21:25

标签: java memory-management garbage-collection weak-references strong-references

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

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.
}

1 个答案:

答案 0 :(得分:1)

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

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

你怎么知道听众是垃圾收集的?您可能会检查它是否存在于后端WeakHashMap中。它不存在所以你声称它是gc'ed。但实际上它从未加入其中。如果这是正确的,请告诉我。

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