什么时候应该使用弱引用?

pet*_*ust 17 c# java weak-references

我最近遇到了一段带有WeakReferences的Java代码 - 我从未见过它们已部署,尽管我们在介绍时遇到过它们.这是应该常规使用的东西还是只有在遇到内存问题时?如果是后者,它们是否可以轻松改装或代码是否需要严格的重构?普通的Java(或C#)程序员通常会忽略它们吗?

编辑过度使用WR可以造成任何损害吗?

Mat*_*ker 22

弱引用都是关于垃圾收集.一个标准的对象不会"消失",直到所有对它的引用被切断,这意味着所有的各种对象必须对它的引用都将被免职之前,垃圾回收会考虑的垃圾.

仅仅因为您的对象被其他对象引用而使用弱引用并不一定意味着它不是垃圾.它仍然可以被GC拾取并从内存中删除.

一个例子:如果我的应用程序中有一堆Foo对象,我可能想使用Set来保存我所有Foo的中心记录.但是,当我的应用程序的其他部分通过删除对它的所有引用来删除Foo对象时,我不希望我的Set的剩余引用保留到该对象以防止它被垃圾收集!真的,我只是希望它从我的集合中消失.这就是你使用类似弱集(Java有一个WeakHashMap)的东西,它使用对其成员的弱引用而不是"强"引用.

如果您的对象在您想要它们时没有被垃圾收集,那么您在簿记中出错了,还有一些内容仍然存在您忘记删除的引用.使用弱引用可以缓解这种记帐的痛苦,因为你不必担心他们保持一个对象"活着",并取消垃圾收集,但你不具备使用它们.


Luc*_*ero 16

只要您想要对对象进行引用而不自己保持对象存活,就可以使用它们.这对于许多类似缓存的功能来说都是如此,但在事件处理中也起着重要作用,订阅者不应通过订阅事件来保持活跃.

一个小例子:一个刷新一些数据的计时器事件.任何数量的对象都可以在计时器上订阅以获得通知,但是他们在计时器上订阅的这个事实不应该使它们保持活动状态.所以计时器应该对对象有弱引用.


Ste*_*n C 8

过度热情地使用WR可以造成任何损害吗?

是的,它可以.

一个问题是弱引用会使您的代码更复杂并且可能容易出错.任何使用弱引用的代码都需要处理每次使用它时引用被破坏的可能性.如果过度使用弱引用,最终会编写大量额外代码.(您可以通过隐藏负责检查的方法后面的每个弱引用来缓解这种情况,并根据需要重新创建丢弃的对象.但这可能不一定那么简单;例如,如果重新创建过程涉及网络访问,你需要应对重新创建失败的可能性.)

第二个问题是使用弱引用存在运行时开销.显而易见的成本是创建弱引用并调用get它们.不太明显的成本是每次GC运行时都需要进行大量的额外工作.

最后一个问题是,如果您对应用程序很可能在将来需要的某些内容使用弱引用,则可能会产生重复重新创建它的成本.如果此成本很高(就CPU时间,IO带宽,网络流量而言),您的应用程序可能会因此而表现不佳.你可能最好给JVM提供更多内存,而根本不使用弱引用.

当然,这并不意味着你应该完全避免使用弱引用.只是你需要仔细思考.您可能应首先在应用程序上运行内存分析器,以确定内存使用问题源于何处.