如何在Java中实现将某些引用显式标记为“不需要的”?
在我看来,我发现了一种情况,标准的垃圾收集算法不能很好地使用 假设我有一个对象A,它在构造时将自身添加为对象B事件的事件侦听器。由于对象具有将自身添加为侦听器所需的所有数据,因此它还具有将自身从侦听器中删除的数据 不幸的是,GC无法启动删除过程,因为在显式删除之前,对象将在侦听器列表中引用 因此,这意味着任何一个对象都不应该将自身添加为侦听器,或者应该有一种方法将某些引用标记为不重要。在后一种情况下,即使存在对对象的一些引用,GC也会启动垃圾收集——如果它们只是无关紧要的情况 显然,程序员必须清除一些方法中所有不重要的引用,比如dispose或finalize 我理解,这种直接实现将是一种安全漂白剂。例如,若程序员违反了处理契约,垃圾收集将提供不正确的引用如何在Java中实现将某些引用显式标记为“不需要的”?,java,garbage-collection,disposable,Java,Garbage Collection,Disposable,在我看来,我发现了一种情况,标准的垃圾收集算法不能很好地使用 假设我有一个对象A,它在构造时将自身添加为对象B事件的事件侦听器。由于对象具有将自身添加为侦听器所需的所有数据,因此它还具有将自身从侦听器中删除的数据 不幸的是,GC无法启动删除过程,因为在显式删除之前,对象将在侦听器列表中引用 因此,这意味着任何一个对象都不应该将自身添加为侦听器,或者应该有一种方法将某些引用标记为不重要。在后一种情况下,即使存在对对象的一些引用,GC也会启动垃圾收集——如果它们只是无关紧要的情况 显然,程序员必须清
因此,问题是:是否有一些库或模式来实现这种关系?如果您只是希望管理对象生命周期以引用它,而不是作为侦听器,那么您可以将侦听器集合更改为类似于的“弱”集合。这样的集合用于避免在清除所有其他引用后使对象保持活动状态。如果您只想将对象生命周期管理为引用它而不是作为侦听器,那么您可以将侦听器集合更改为类似的“弱”集合。这样的集合用于避免在清除所有其他引用后使对象保持活动状态。查看Java中的不同子类。我想这就是您要寻找的查看Java中的不同子类。我认为这就是您要寻找的一般来说,当您希望对象被垃圾回收时,您应该将删除引用作为您的工作。这是在垃圾收集环境中管理内存的一部分 例如:
class MyInternalFrame extends JInternalFrame implements ActionListener {
...
void removeSelfAndDispose() {
for(JMenuItem button : parent.getMenuItems())
button.removeActionListener(this);
dispose();
}
}
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;
}
...
}
}
}
但是,最好避免存储这些持久性引用。例如,使用静态嵌套类,而不是在容器上实现侦听器
可以使用来编造一个不阻止垃圾收集的侦听器,例如:
class MyInternalFrame extends JInternalFrame implements ActionListener {
...
void removeSelfAndDispose() {
for(JMenuItem button : parent.getMenuItems())
button.removeActionListener(this);
dispose();
}
}
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;
}
...
}
}
}
但这是粗略的,不应该依赖。我们无法控制垃圾收集何时运行,因此这样做可能会导致不可预测的行为。我们保留引用的对象仍然存在,并在您认为它已被删除后响应事件
更可靠的方法是简单地防止不需要的引用被放置在适当的位置,或者在适当的时候故意删除它们。通常,当您希望对象被垃圾收集时,您应该将删除引用作为您的工作。这是在垃圾收集环境中管理内存的一部分 例如:
class MyInternalFrame extends JInternalFrame implements ActionListener {
...
void removeSelfAndDispose() {
for(JMenuItem button : parent.getMenuItems())
button.removeActionListener(this);
dispose();
}
}
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;
}
...
}
}
}
但是,最好避免存储这些持久性引用。例如,使用静态嵌套类,而不是在容器上实现侦听器
可以使用来编造一个不阻止垃圾收集的侦听器,例如:
class MyInternalFrame extends JInternalFrame implements ActionListener {
...
void removeSelfAndDispose() {
for(JMenuItem button : parent.getMenuItems())
button.removeActionListener(this);
dispose();
}
}
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;
}
...
}
}
}
但这是粗略的,不应该依赖。我们无法控制垃圾收集何时运行,因此这样做可能会导致不可预测的行为。我们保留引用的对象仍然存在,并在您认为它已被删除后响应事件
更可靠的方法是简单地防止不需要的引用被放置在适当的位置,或者在适当的时候故意删除它们。对于侦听器的特定情况,您应该在不再需要它们时删除它们。其他情况可能会使用弱引用或finalize,但对于通常不起作用的侦听器来说,对于侦听器的特定情况,您应该在不再需要它们时删除它们。其他情况可能使用弱引用或finalize,但对于侦听器来说,这通常不起作用。