有弱引用的实际用途吗?

可能重复:
弱引用 – 它们有多有用?

由于垃圾收集器可以随时声明弱引用,是否有使用它们的实际原因?

如果你想保留一个引用,只要它在别的地方使用,例如一个监听器,你可以使用一个弱引用。

WeakHashMap可以用作派生数据的密钥的短暂caching。 它也可以用来保存关于其他对象的信息,而不知道什么时候这些对象被丢弃。

BTW软引用就像弱引用,但它们不会总是立即清理。 GC会一直放弃弱引用,并在可能的时候保留软引用。

还有一种称为“幻影参考”的参考。 这在GC清理过程中使用,并且指的是由于正在清理过程中而不能被“正常”代码访问的对象。

由于垃圾收集器可以随时声明弱引用,是否有任何实际的理由来使用它?

当然有实际的理由来使用它。 如果框架devise者花费巨大的代价去build立一个不切实际的弱参考系统,那你会觉得奇怪吗?

我想你想问的问题是:

什么是人们使用弱引用的现实情况?

有许多。 一个常见的就是实现一个性能目标。 当调整应用程序的性能时,往往必须在更多的内存使用和更多的时间使用之间进行权衡。 假设有一个复杂的计算,你必须执行很多次,但是计算是“纯粹的” – 答案只取决于参数,而不取决于外生状态。 你可以构build一个caching – 一个从参数到结果的映射 – 但是它使用内存。 你可能再也不会问这个问题了,那么记忆就会被浪费掉。

弱引用可能解决这个问题; caching可能会变得非常大,因此如果多次询问相同的问题,则会节省时间。 但是,如果caching变得足够大,垃圾收集器需要回收空间,那么可以安全地进行。

不利的一面是垃圾收集器的清理策略被调整来满足整个系统的目标,而不是你特定的caching问题。 如果GC策略和你想要的caching策略足够一致,那么弱引用就是解决这个问题的一个非常实用的解决scheme。

如果WeakReference是对象的唯一引用,并且您希望该对象四处移动,则应该使用SoftReference 。

WeakReference最适用于那些会有其他对象引用的情况,但是你不能(或不想)必须检测那些不再使用的引用。 然后, 另一个引用将防止对象被垃圾收集,而WeakReference只是另一种获取同一对象的方式。

两个常见的用例是:

  1. 为了保存关于特定对象的附加(通常是昂贵计算但可重现的)信息,而这些信息不能直接修改,而且您的生命周期几乎无法控制。 WeakHashMap是持有这些引用的完美方式:WeakHashMap中的关键字只能被弱化,所以当关键字被垃圾收集时,这个值也可以从Map中去除,从而被垃圾收集。
  2. 为了实施某种事件或通知系统,“听众”使用某种协调员进行注册,这样当有事情发生时,他们可以得到通知 – 但是当你不想阻止这些听众在他们到达时被垃圾收集他们的生命的结束。 一个WeakReference会在它仍然存在的时候指向这个对象,但是一旦原始的对象被垃圾收集,就指向“null”。

我们使用它是因为这个原因 – 在我们的例子中,我们有各种各样的必须注册服务的监听器。 该服务保持弱引用的侦听器,而实例化的类保持强引用。 如果这些课程随时得到GC的帮助,那么这个弱点就是听众留下的所有东西,然后就会被GC化。 这使得跟踪中介类更容易。

弱引用最常见的用法是“查找”地图中的值。

对于普通(硬)值引用,如果映射中的值不再在其他地方引用,则通常不需要查找。 对于弱引用的映射值,一旦没有其他引用,对象就成为垃圾收集的候选对象

地图本身具有(唯一的)对该对象的引用的事实不会阻止它被垃圾收集,因为引用是一个引用

为了防止内存泄漏,请参阅这篇文章的细节。

弱引用是一个引用,它不保护垃圾回收器收集的引用对象。

  • 仅被弱引用引用的对象被认为是不可访问的(或“弱可达性”),因此可以在任何时候收集。
  • 使用弱引用来避免不必要的对象引用内存。 一些垃圾收集语言function或支持各种级别的弱引用,如Java,C#,Python,Perl或Lisp。
  • 垃圾收集用于减less内存泄漏和数据损坏的可能性。 垃圾收集主要有两种types:追踪和引用计数。 引用计数schemelogging对给定对象的引用数量,并在引用计数变为零时收集对象。 引用计数不能收集循环(或循环)引用,因为一次只能收集一个对象。 因此不能被其他对象直接引用并且不能被访问的相互引用对象组可以永久存在; 如果一个应用程序不断产生这样的不可达对象的不可达组,这将会产生内存泄漏的效果。 弱引用可以用来解决循环引用的问题,如果引用循环是通过使用组引用的弱引用来避免的。
  • 弱引用也被用来通过允许程序通过仅仅弱引用它们来指示哪些对象不是关键的,来最小化内存中不必要的对象的数量。

我通常使用它的某种types的caching。 最近访问的项目立即可用,并在caching未命中的情况下重新加载项目(DB,FS,无论)。

我使用WeakSet来编码图表中的链接。 如果一个节点被删除,链接自动消失。