1

在我看来,我发现了一种情况,标准的垃圾收集算法不能很好地使用。

假设我有一些 object A,它在构造时将自身添加为来自 object 的事件的事件侦听器B。由于对象具有将自身添加为侦听器所需的所有数据,因此它也具有将自身从侦听器中删除的数据。

不幸的是,删除过程不能由 启动GC,因为对象将在侦听器列表中引用,直到显式删除。

因此,这意味着任何一个对象都不应该将自己添加为侦听器,或者应该有一种方法可以将某些引用标记为不重要。在后一种情况下GC,即使存在对对象的一些引用,也会启动垃圾收集——如果它们只是“不重要”的情况。

显然,程序员应该有义务在诸如disposeor之类的方法中清除所有不重要的引用finalize

我知道这种直接实施将是一种安全漂白。例如,如果程序员违反了处置契约,垃圾收集将提供不正确的引用。

所以,问题是:是否有一些库或模式来实现这种关系?

4

3 回答 3

3

如果您只想将对象生命周期管理为对它的引用而不是作为侦听器,那么您可以将侦听器集合更改为像WeakHashMap这样的“弱”集合。这样的集合使用弱引用来避免在清除所有其他引用后保持对象处于活动状态。

于 2014-12-01T17:03:27.020 回答
2

通常,当您希望对象被垃圾收集时,您应该将删除引用作为您的工作。这是在垃圾收集环境中管理内存的一部分。

只是,例如:

class MyInternalFrame extends JInternalFrame implements ActionListener {
    ...

    void removeSelfAndDispose() {
        for(JMenuItem button : parent.getMenuItems())
            button.removeActionListener(this);
        dispose();
    }
}

但是,最好避免存储这些持久引用。例如,使用static嵌套类而不是在容器上实现侦听器。

可以使用WeakReference来构造一个不会阻止垃圾收集的侦听器,例如:

class MyInternalFrame extends JInternalFrame {
    ...

    MyInternalFrame() {
        for(JMenuItem button : parent.getMenuItems())
            button.addActionListener(new WeakListener(this, button));
    }

    static class WeakListener implements ActionListener {
        final Reference<JInternalFrame> ref;
        final AbstractButton button;

        WeakListener(JInternalFrame frame, AbstractButton button) {
            ref = new WeakReference<JInternalFrame>(frame);
            this.button = button;
        }

        @Override
        public void actionPerformed(ActionEvent ae) {
            JInternalFrame frame = ref.get();
            if(frame == null) {
                button.removeActionListener(this);
                return;
            }

            ...
        }
    }
}

但这是粗略的,不应依赖。我们无法控制垃圾收集何时运行,因此这样做可能会导致不可预知的行为。(我们保留引用的对象仍然存在,并在您认为它已被删除后响应事件。)

简单地防止不需要的引用被放置或在适当的时候故意删除它们更可靠。

于 2014-12-01T17:14:53.040 回答
1

查看Java中Reference的不同子类。我想这就是你要找的

于 2014-12-01T17:04:19.950 回答