为什么我需要在使用弱引用时找到与listerner对象具有完全相同生命周期的对象?

时间:2016-02-23 15:30:20

标签: java event-handling weak-references

我正在阅读阅读Brian Goetz在2005年撰写的一些旧文章,这些文章可以在IBM developerWorks上阅读。 One他们让我很困惑。

在这篇关于如何设计好的事件模型的文章中,他谈到了内存泄漏对糟糕的侦听器使用的可能性。在这里,我注意到他提到如果我想存储带有弱引用的lisenter,我将不得不找到一个与侦听器对象具有相同生命周期的对象。

  

有时建议用于处理已失效侦听器(*)的一种方法是使用弱引用。虽然这种方法是可行的,但实施起来相当棘手。要使它工作,你需要找到另一个对象,其生命周期正好是你的监听器的生命周期,并安排它保持对你的监听器的强引用,并不总是那么容易。

     

*注意:已失效的侦听器是不再使用的侦听器,但未被取消注册。

这很奇怪。 WeakHashMap不够好吗?如果没有,为什么?或者WeakHashMap只是我需要的“对象”?这看起来并不棘手...

我也注意到这篇文章来自2005年。如果它只是遗留问题,那么变化何时发生?我想我需要知道它,因为我最终可能会处理旧的JDK。

1 个答案:

答案 0 :(得分:1)

问题在于,如果你对一个听众(或者,就此而言,任何事情)保持一个强烈的引用,它将比它的实用性更长久。 (在文章的示例代码中,他展示了一个监听器被注册的情况,然后时间过去了,然后监听器被取消注册。但是如果在它们之间抛出异常,那么监听器会保持注册时间超过它的时间。不要这样做。)如果OTOH你依赖于弱引用,但是过早地删除所有强引用,那么可以在它的时间之前收集监听器。解决方案是在足够长的时间内保持强大的参考。通过将该引用存储在具有相同“生命周期”的对象中,这就是他的意思。

使用Map,您可以让 WeakHashMap过长地保留引用。这解决了持有太长时间问题*,但这仍然让你过早地失去听众。因此,他希望你在其他已经存在足够长时间的内容中强有力地引用听众。

说起来容易做起来难,这就是为什么他说“实施起来很棘手”。

*它部分地解决了持有太长的问题。问题是GC不能保证及时运行,或者确实运行。因此,即使使用弱引用,您最终也可能会失去一个已失效的监听器。