Hash-consingは、指定されたオブジェクトのコピーを1つだけ保持します。つまり、2つのオブジェクトが意味的に等しい場合(同じ内容の場合)、それらは物理的に等しくなければなりません(メモリ内の同じ場所)。この手法は、通常、グローバルハッシュセットを保持し、ハッシュセット内のオブジェクトと等しくない場合にのみ新しいオブジェクトを作成することによって実装されます。F#のハッシュコンサインと.netの弱いハッシュテーブル。
さらに、ハッシュテーブル内のオブジェクトは、ハッシュテーブル以外のオブジェクトによって参照されない場合は収集可能である必要があります。さもなければ、ハッシュテーブルには弱い参照が含まれているはずです。
問題は、一定の時間が必要であるため、さらに浅いハッシュと平等テストを必要とするため、さらに複雑になります。したがって、オブジェクトには、新しいオブジェクトがテーブルに追加されるときに増分される固有の識別子があります。
System.Collections.Generic.Dictionary<key, node>
を使用する実装があります。key
は、ノードの浅い要約(デフォルトのハッシュと等価性テストに適しています)を与えるタプルであり、node
がオブジェクトです。唯一の問題は、Dictionary
がノードへの強い参照を保持していることです!
Dictionary
〜WeakReference
を使用できますが、これはダングリングリファレンスを指すキーを解放しません。
System.Runtime.CompilerServices.ConditionalWeakTable
を使用している提唱者もいますが、このクラスは逆の処理をしているようです。キーを収集するときに値を解放しますが、値を収集するときにはキーを解放する必要があります。
一つはSystem.Runtime.CompilerServices.ConditionalWeakTable<node, node>
を使用して試みることができるが、私は、カスタムハッシュと平等のテストが必要になる...とConditionalWeakTable
ではなく、デフォルトのハッシュ関数を使用して、GetHashCode()
仮想メソッドを使用するないを文書化されています。
私の質問:値が弱い参照を保持し、参照がぶら下がるとキーを解放するDictionary
のいくつかの同等のものがありますか?
値を収集するとすぐにキーを解放する必要がありますか?または、要件を緩和して、ちょっと後でキーを解放することはできますか? –
私はそれらをすぐに解放する必要はありません - それは私がそれらが蓄積し、無駄に多くのメモリを消費したくないということだけです。私は、別のスレッドを実行して定期的に参照がついていないキーを殺すことを考えましたが、これは複雑で同時実行エラーが発生しやすいようです。 –
それは価値があるのですが、私は 'Weak'モジュールのハッシュテーブルと' WeakHashMap'を使ったJava実装を使ってOCaml実装をしています。 –