我有以下类层次结构。出于某种原因,即使我保持对它的强烈引用,我的听众也会收集垃圾。
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.
}
答案 0 :(得分:1)
如果你仍然对MyModule有强烈的引用,MyListener就不可能收集垃圾。
要么你没有设置正确的子模块,要么你没有设置正确的监听器,或者你永远不会将你的监听器添加到后端WeakHashMap(我猜这是最有可能的)。
你怎么知道听众是垃圾收集的?您可能会检查它是否存在于后端WeakHashMap中。它不存在所以你声称它是gc'ed。但实际上它从未加入其中。如果这是正确的,请告诉我。
首先检查你是否真的有对Module和SubModule的强引用。如果有,则检查SubModule是否具有对MyListener的有效引用。