我想知道弱引用在内部是如何工作的,例如在.NET或Java中。我的两个基本想法是:
这两种解决方案看起来都不干净也不高效。有没有人知道这到底是怎么做的?
发布于 2009-04-23 11:48:54
我不确定我是否理解了您的问题,但是您可以查看WeakReference类的实现以及它在Java语言中的超类引用。它有很好的注释,您可以看到它有一个由GC特殊处理的字段和另一个由VM直接使用的字段。
发布于 2009-04-23 08:32:53
在.NET中,当创建WeakReference
时,会要求GC提供一个表示引用的句柄/不透明令牌。然后,当需要时,WeakReference
使用这个句柄来询问GC该句柄是否仍然有效(即原始对象仍然存在)-如果是的话,它可以获得实际的对象引用。
因此,这是针对对象地址构建令牌/句柄列表(并假设在碎片整理期间维护该列表)。
我不确定我100%理解了这三个项目,所以我不太愿意去猜测哪一个(如果有的话)最接近。
发布于 2013-08-03 07:20:39
似乎弱引用的实现在行业中是保密的;-)。例如,到目前为止,wikipedia article缺乏任何实现细节。然后看看上面的答案(包括被接受的答案):“去看看源代码”或“我想”;-\。
在所有答案中,只有一个提到Python的PEP205是有洞察力的。正如它所说的,对于任何单个对象,如果我们将弱引用视为实体本身,则最多只能有一个弱引用。
其余部分描述了Squirrel语言的实现。所以弱引用本身就是一个对象,当你把弱引用放在一些容器中的时候,实际上你把引用放到了弱引用对象上。每个ref-countable对象都有字段来存储指向其弱引用的指针,在实际请求该对象的弱引用之前,该字段为NULL。每个对象都有方法来请求弱引用,该方法要么从字段中返回现有的(单例)弱引用,要么创建它并在字段中缓存。
当然,虚弱引用指向原始对象。所以,你只需要遍历处理对象引用的所有可用的地方,并添加对弱引用的透明处理(即自动取消引用它)。(“透明”的替代方法是添加虚拟的“访问”方法,该方法对大多数对象都是标识的,而对弱引用则是实际的解引用。)
当对象有指向其弱引用的指针时,该对象可以在自己的析构函数中NULLify该弱引用。
这个实现非常干净(没有神奇的“调用GC”之类的东西),并且运行时成本为O(1)。当然,这是非常贪婪的内存-需要添加+1指针字段到每个对象,即使通常对于90+%对象将是空的。当然,VHLL对于每个对象已经有很大的内存开销,并且可能有机会压缩不同的“额外”字段。例如,对象类型通常是一个很小的枚举,因此可以将类型和某种弱引用合并到单个机器字中(例如,将弱引用对象放在单独的领域中,并对其使用索引)。
https://stackoverflow.com/questions/780738
复制相似问题