Pointers 为什么弱点有用?

Pointers 为什么弱点有用?,pointers,garbage-collection,weak-references,Pointers,Garbage Collection,Weak References,我一直在阅读有关垃圾收集的文章,寻找在我的编程语言中包含的特性,但我遇到了“弱点”。发件人: 弱指针就像指针一样, 除了来自弱者的引用 指针不能防止垃圾 集合和弱指针 以前检查过它们的有效性吗 它们被使用 弱指针与 垃圾收集器,因为内存 事实上,他们提到的 有效,但包含不同的 物体比它弱的时候 指针已创建。因此,每当 垃圾收集器回收内存,它 必须检查是否有 引用它的弱指针,以及 将它们标记为无效(不需要 以这种天真的方式实现) 我以前从未听说过弱点。我想在我的语言中支持许多特性,但在这种情况下,

我一直在阅读有关垃圾收集的文章,寻找在我的编程语言中包含的特性,但我遇到了“弱点”。发件人:

弱指针就像指针一样, 除了来自弱者的引用 指针不能防止垃圾 集合和弱指针 以前检查过它们的有效性吗 它们被使用

弱指针与 垃圾收集器,因为内存 事实上,他们提到的 有效,但包含不同的 物体比它弱的时候 指针已创建。因此,每当 垃圾收集器回收内存,它 必须检查是否有 引用它的弱指针,以及 将它们标记为无效(不需要 以这种天真的方式实现)


我以前从未听说过弱点。我想在我的语言中支持许多特性,但在这种情况下,我一生都想不出这样做有什么用处。为什么要使用弱指针?

一个真正大的指针是缓存。让我们思考一下缓存是如何工作的:

缓存背后的想法是将对象存储在内存中,直到内存压力变得如此之大,以至于某些对象需要被推出(当然,也可能是显式无效的)。因此,您的缓存存储库对象必须以某种方式保留这些对象。通过弱引用保持它们,当垃圾回收器因为内存不足而查找要消耗的内容时,仅由弱引用引用的项目将显示为垃圾回收的候选项。缓存中当前正被其他代码使用的项将具有仍处于活动状态的硬引用,因此这些项将受到垃圾收集的保护


在大多数情况下,您不会使用自己的缓存机制,但使用缓存是很常见的。假设您希望有一个属性引用缓存中的对象,并且该属性在作用域中保留很长时间。您希望从缓存中获取对象,但如果该对象不可用,则可以从持久化存储中获取。如果压力太大,您也不希望强制特定对象留在内存中。因此,您可以使用对该对象的弱引用,这将允许您在该对象可用时获取它,但也允许它从缓存中掉出。

例如,弱引用可用于缓存场景-您可以通过弱引用访问数据,但如果长时间不访问数据或内存压力很大,GC可以释放它。

当您希望保留对象的缓存列表时,使用它们,但如果对象的“真正”所有者已经处理完,则不能阻止这些对象被垃圾收集


web浏览器可能有一个历史对象,该对象保留对浏览器加载到其他位置并保存在历史/磁盘缓存中的图像对象的引用。web浏览器可能会使其中一个图像过期(用户已清除缓存、缓存超时已过等),但页面仍将具有引用/指针。如果页面使用弱引用/指针,对象将按预期消失,内存将被垃圾收集。

一个典型的使用案例是存储其他对象属性。假设您有一个具有固定成员集的类,并且希望从外部添加更多成员。因此,创建一个dictionary对象->属性,其中键是弱引用。然后,字典不会阻止密钥被垃圾收集;删除对象还应触发删除WeakKeyDictionary中的值(例如通过回调)。

另一个示例。。。不完全是缓存,但类似:假设一个I/O库提供了一个对象,该对象封装了一个文件描述符并允许访问该文件。收集对象时,文件描述符关闭。希望能够列出当前打开的所有文件。如果对该列表使用强指针,则文件永远不会关闭

如果您的语言的垃圾收集器无法收集循环数据结构,那么您可以使用弱引用使其能够收集循环数据结构。通常,如果有两个对象相互引用,但没有其他外部对象引用这两个对象,那么它们将成为垃圾收集的候选对象。但是,天真的垃圾收集器不会收集它们,因为它们包含相互引用


要解决此问题,请使一个对象对第二个对象具有强引用,但第二个对象对第一个对象具有弱引用。然后,当对第一个对象的最后一个外部引用消失时,第一个对象成为垃圾收集的候选对象,紧接着是第二个对象,因为现在它唯一的引用是弱的。

垃圾收集的原因是,在像C这样的语言中,内存管理完全在程序员的显式控制下,当对象所有权被传递时,特别是在线程之间,或者更难的是,在共享内存的进程之间,避免内存泄漏和指针悬空可能变得非常困难。如果这还不够困难,那么您还必须处理需要访问的对象多于一次存储在内存中的对象的问题。您需要有一种方法来释放一些对象一段时间,以便其他对象可以存储在内存中

因此,一些语言(例如Perl、Lisp、Java)提供了一种机制,在这种机制中,您可以停止“使用”对象,垃圾收集器最终会发现这一点并释放用于该对象的内存。它正确地做到了这一点,而程序员不必担心所有可能出错的方法(尽管程序员有很多方法会把事情搞砸)

如果从概念上讲,将访问对象的次数乘以计算对象值所需的时间,并可能再次乘以对象不可用的成本或自保持