java - 弱引用是否有实际用途?
可能重复:
弱参考 - 它们有多大用处?
由于垃圾收集器可以随时声明弱引用,是否有任何实际的理由使用它们?
9个解决方案
44 votes
如果你想保留对某些东西的引用,只要它在其他地方使用,例如 一个监听器,你可以使用弱引用。
WeakHashMap可以用作派生数据的密钥的短期缓存。 它还可以用于保存有关其他对象的信息,并且您不知道何时丢弃这些对象。
BTW Soft References就像弱引用一样,但它们并不总是立即清理。 GC将始终丢弃弱引用,并尽可能保留软引用。
还有另一种称为幻影参考的参考。 这用于GC清理过程,并指的是一个对象无法正常访问"正常" 代码,因为它在清理过程中。
Peter Lawrey answered 2019-08-12T07:09:56Z
28 votes
由于垃圾收集器可以在任何时候声称弱引用,是否有任何实际的理由使用它?
当然有使用它的实际原因。 如果框架设计者花费巨大的代价建立一个不切实际的弱参考系统,你会怎么想,这将是非常奇怪的?
我想你想问的问题是:
人们使用弱引用的现实情况是什么?
有许多。 常见的是实现性能目标。 在对应用程序进行性能调整时,通常必须在更多内存使用和更多时间使用之间进行权衡。 假设有一个复杂的计算,你必须多次执行,但计算是纯粹的" - 答案仅取决于论据,而不取决于外生状态。 您可以构建一个缓存 - 从参数到结果的映射 - 但然后使用内存。 你可能永远不会再问这个问题,然后就会浪费内存。
弱引用可能解决了这个问题; 缓存可能会变得非常大,因此如果多次询问相同的问题,则会节省时间。 但是如果缓存变得足够大以至于垃圾收集器需要回收空间,那么它可以安全地进行。
缺点当然是垃圾收集器的清理策略被调整为满足整个系统的目标,而不是特定的缓存问题。 如果GC策略和所需的缓存策略充分对齐,那么弱引用是解决此问题的高度实用的解决方案。
Eric Lippert answered 2019-08-12T07:11:05Z
13 votes
如果WeakReference是对象的唯一引用,并且您希望对象挂起,则应该使用SoftReference。
WeakReferences最适用于有对象的其他引用的情况,但是你不能(或者不想要)检测何时不再使用那些其他引用。 然后,另一个引用将阻止对象被垃圾收集,而WeakReference将只是另一种获取相同对象的方式。
两个常见用例是:
用于保存有关您无法直接修改的特定对象的额外(通常是昂贵计算但可重现的)信息,以及您无法控制其生命周期的信息。 WeakHashMap是保存这些引用的完美方式:WeakHashMap中的键只是弱保存,因此当密钥被垃圾收集时,该值也可以从Map中删除,因此被垃圾收集。
用于实现某种事件或通知系统,其中"听众" 在某些协调员处注册,以便在发生某些事情时通知他们 - 但是如果您不希望阻止这些听众在他们的生命结束时被垃圾收集。 WeakReference将指向该对象,但它仍处于活动状态,但指向" null" 一旦原始对象被垃圾收集。
Bill Michell answered 2019-08-12T07:12:02Z
12 votes
我们出于这个原因使用它 - 在我们的例子中,我们有各种必须注册服务的监听器。 该服务保持对侦听器的弱引用,而实例化的类保留强引用。 如果这些类在任何时候得到了GC,那么弱引用就是听众的剩余部分,然后也是GC。 它使得更容易跟踪中间类。
Noah answered 2019-08-12T07:12:27Z
8 votes
弱引用的最常见用法是" lookup"中的值。地图。
使用普通(硬)值引用时,如果地图中的值不再在其他地方引用它,您通常不再需要查找。 对于弱引用的映射值,一旦没有其他引用,该对象就成为垃圾收集的候选对象
地图本身具有(唯一)对象的引用这一事实不会阻止它被垃圾收集,因为引用是弱引用
Bohemian answered 2019-08-12T07:13:06Z
3 votes
要防止内存泄漏,请参阅此文章以获取详细信息。
Óscar López answered 2019-08-12T07:13:30Z
3 votes
弱引用是一种引用,它不保护引用对象不被垃圾收集器收集。
考虑仅由弱引用引用的对象无法到达(或者"弱可达")因此可以在任何地方收集时间。
弱引用用于避免保留引用的内存不需要的物品。 一些垃圾收集语言的功能或支持各种级别的弱引用,例如Java,C#,Python,Perl或Lisp的。
垃圾收集用于减少内存泄漏的可能性和数据损坏。 垃圾收集有两种主要类型:跟踪和引用计数。 参考计数方案记录了对给定对象的引用数量,并在何时收集对象引用计数变为零。 参考计数无法收集循环(或循环)引用,因为只有一个对象一次收集。 相互引用的对象组因此,不能被其他对象直接引用并且无法访问永久居住; 如果应用程序不断生成这样的无法到达的无法访问的对象组内存泄漏的影响。 弱引用可用于解决问题如果避免参考循环,循环引用的问题对组内的某些引用使用弱引用。
弱引用也用于最小化不必要的数量通过允许程序指示哪些对象在内存中的对象仅仅弱引用它们并不重要。
Bhushan answered 2019-08-12T07:14:30Z
2 votes
我通常将它用于某种类型的缓存。 最近访问的项目立即可用,如果缓存未命中,则重新加载项目(DB,FS,等等)。
Jan Zyka answered 2019-08-12T07:14:57Z
0 votes
我使用WeakSet来编码图表中的链接。 如果删除节点,链接将自动消失。
Neil G answered 2019-08-12T07:15:26Z