3

Clojure言語を拡張して、ACI保証の参照をACID保証のdref(耐久性のある参照)に拡張しようとしています。APIは、単純にを呼び出すためのものです(dref key value)。ここでkey、は基になるデータストア(現在の実装ではBDB JE)で使用されるキーの文字列でありvalue、drefを初期化する必要があるオブジェクトです。keyDBにすでに存在する場合は、代わりに保存された値が使用されます。

同じキーで複数のdrefを作成でき、それらを同期する必要があります。つまり、キー「A」を持つ1つのdrefが、キー「A」で書き込まれたり読み取られたりするトランザクションに参加する場合、(ensure)キー「A」を持つ他のすべてのdrefはトランザクションである必要があります。同期:読み取りロックと書き込みロックを使用して、これらのdrefを含むトランザクションに順序を付ける必要があります。より広い意味では、同じキーを持つ複数のメモリ内drefが存在する場合がありますが、そのキーを持つすべてのdrefは単一の論理オブジェクトです。

明らかな理由から、この単一の論理drefが単一の具象インメモリdrefで実装されていることを確認する方がはるかに簡単です。そうすれば、同期するものは何もありません。どうすればよいですか?

明白な答えは、keyにキー設定されたオブジェクトプールを使用することです。次に、Clojureは静的getInstance(key,value)メソッドを呼び出して、存在する場合はプールから取得し、存在しない場合は作成してプールにデータを入力します。このアプローチの問題は、完了時にClojureにオブジェクトを解放させる簡単な方法がないことです。メモリリークのある都市。強い参照を持つオブジェクトが収集されないようにし、それらがプールに存在するようにする必要があります。別のプロセスが同じキーを持つ新しいdrefを作成する可能性があり、同じキーを持つ他のdrefとのトランザクションの安全性がないため、プールがまだ使用されている論理drefへの参照を失うと悲惨なことになります。

そのため、強くない参照を使用したバージョンWeakHashMapまたは何かが必要です(SoftReferenceGCでもう少し気が進まない場合は、を使用することをお勧めします)。それで:

  1. を使用するHashMap<String,SoftReference<DRef>>場合、エントリの値(SoftReference)が収集された場合に、マップがエントリを削除するようにするにはどうすればよいですか?ある種のデーモンスレッド?
  2. GCのプールをスレッドセーフにするにはどうすればよいですか?SoftReferenceまたは、GCがレベルで動作していて、デーモンスレッドがそのレベルで動作しているので、それについて心配する必要はありませんMapか?
  3. 関連するメモとして、デーモンスレッドが実行されていることを確認するにはどうすればよいですか?キャッチされない場合にJVM全体をクラッシュさせる例外をスローせずに停止できる方法はありますか?その場合、必要に応じて新しいものを監視して開始するにはどうすればよいですか?
4

3 に答える 3

1

Psssst....テラコッタの分散共有オブジェクトを再作成しています。Terracottaの内部はこれと非常によく似ていますが、(DSOでは)ロード時にバイトコード操作を使用してフィールドへのすべての読み取りと書き込みをインターセプトすることに依存していますが、Clojureではかなり簡単です。

Terracottaの実装を確認したい場合は、ClientObjectManager(http://svn.terracotta.org/svn/tc/dso/trunk/code/base/dso-l1/src/com/tc/object/)が共有オブジェクトを管理するメインのクライアント側クラス。pojoToManagedをチェックして、TCObjectImplの関連コードのいくつかを調べてください。

1,2)ボブ・リーの講演「仮想マシンの幽霊」が役立つかもしれません。これは、この種のものについて私が見つけた最高の参考資料です。SoftReferencesとGC(およびファイナライザー)は、ちょっと注意が必要です。

3)キャッチされない例外ハンドラーのGoogle..。

于 2010-09-21T01:05:27.507 に答える
1

google-collectionsを試しましたか?

それらには、ソフト/ウィークキーと値を使用して同時ハッシュマップのバリエーションを提供するMapMakerがあります。1つの問題は、ウィーク/ソフトキーの同等性がIDであるということです。これは煩わしいですが、キーが文字列の場合はそれほど多くはありません。

他のライブラリは私が信じていることをします(org.apache.commons.collectionsですが、私はそれらを使用したことはありません)。

于 2010-09-20T21:00:15.553 に答える
0

簡単な答えはおそらく単なるCollections.SynchronizedMap(new WeakHashMap())-ですが、それだけではスレッドセーフな反復は得られません。

1)Map<K, V>自分で実装し、に委任することができますConcurrentHashMap<K, SoftReference<V> >。にを配置SoftReferencesReferenceQueue、デーモンスレッドを使用してマップから参照を削除するか、ReferenceQueue各操作(または各n番目の操作など)の前後を確認することができます。

2)GCは参照を無効にするだけです。マップが乱雑になることを心配する必要はないので、スレッド化の心配はありません。

3)AWT-EventQueueがどのように管理されているかを見ることができます。だが:

-デーモンスレッドは、予期しない例外をスローしないようにおそらく十分に単純です。

-気になる場合は、デーモンスレッドの内容をラップすることができます

for (;;) {
  try {
    //daemon thread loop here
  } catch (Exception ex) {
    //log it, any other possible cleanup
  }
}

エラーが発生しない限り、これは永久に実行されます(この場合、より大きな問題が発生します)。

于 2010-09-20T21:23:55.167 に答える