Hash-consing包含在內存中保留給定對象的一個副本;也就是說,如果兩個對象在語義上相同(相同的內容),那麼它們應該在物理上相同(存儲器中的相同位置)。該技術通常通過保持全局哈希集並僅在不等於哈希集中的對象時創建新對象來實現。F#中的哈希鏈接和.net中的弱哈希表
另一個要求是散列表中的對象應該是可收集的,如果它們沒有被散列表以外的任何東西引用;否則表示,散列表應該包含弱引用。
這個問題更復雜的是需要有恆定的時間,因此淺,哈希和平等測試;因此對象具有一個唯一的標識符,當將新對象添加到表中時,該標識符會增加。
我有一個使用System.Collections.Generic.Dictionary<key, node>
的工作實現,其中key
是一個給出節點的淺層摘要(適用於默認散列和相等測試)的元組,並且node
是對象。唯一的問題是Dictionary
保持對節點的強引用!
我可以使用Dictionary
至WeakReference
's,但這不會釋放指向懸空引用的密鑰。
一些倡導者使用System.Runtime.CompilerServices.ConditionalWeakTable
,但這個類似乎做了相反的事情:它在收集密鑰時釋放值,而在收集值時需要釋放密鑰。
一個可以嘗試使用System.Runtime.CompilerServices.ConditionalWeakTable<node, node>
,但我需要自定義的散列和平等的測試...和ConditionalWeakTable
是記錄不使用GetHashCode()
虛方法,而不是使用默認的散列函數。
因此,我的問題:是否有一些相當於Dictionary
,將保持對值的弱引用,並且當引用變成懸掛時釋放密鑰?
您是否需要在收集該值時立即釋放密鑰?或者你能否放鬆這個要求,並在稍後的某個時間點解鎖? – 2013-03-25 14:27:45
我不需要他們立即被釋放 - 這只是我不希望他們積累和無用地消耗大量的內存。我想過運行另一個線程來週期性地殺死具有懸掛引用的鍵,但這看起來很複雜並且容易出現併發錯誤。 – 2013-03-25 14:34:05
對於它的價值,我也有一個OCaml實現,使用'Weak'模塊的哈希表和一個Java實現'WeakHashMap'。 – 2013-03-25 15:32:47