4

問題文

私は2台のマシンAとBを持っており、どちらもClojureを実行しています。

Bにはメモリデータ構造があります。

Aは、Bのメモリ内のオブジェクトB_Oへの参照/ポインタであるオブジェクトA_Pを保持します。

さて、A_PがAによってGCされていない限り、B_OがBによってGCされたくありません。

ただし、A_PがAによってGC-edされたら(Aの他の何もB_Oを参照せず、Bの他の何もB_Oを参照しません)、B_Oが適格にGC-edされるようにします。

デストラクタを使用した言語でのソリューション

C ++では、これは簡単です-私はデストラクタを使用します。A_PがGC-edを取得すると、AはBにメッセージを送信してB_Oへの外部参照の数をデクリメントします。それが0で、B_0への内部参照も0の場合、B_OはGC-edを取得します。

Java / Clojureのソリューション?

今、私はJavaにデストラクタがないことを知っています。ただし、Clojureにこの問題を回避する方法があるかどうか疑問に思っています。

ありがとう!

4

4 に答える 4

3

実際の分散ガベージコレクタがなければ、良い解決策はありません。C ++でも、参照カウントを実装し、それが実際のガベージコレクターであると偽ったため、これを安全に行うことはできません。ただし、2つのオブジェクトがマシン分割全体で相互にポイントしていて、両方ともローカルで参照されていない場合でも、両方ともゼロ以外の参照カウントを持ち、収集できません。

于 2012-10-10T04:28:02.987 に答える
1

いいえ、Clojure(JVM、CLRに基づく)には、JVMの自動メモリ管理モデルのため、「C++タイプのデストラクタ」がありません。ファイナライザーのようなものもありますが、使用しないことをお勧めします。代わりに、Bのデータへの「ポインタ/参照」を保持するマシンではなく、メッセージパッシングメカニズムに基づいてソリューションをモデル化する必要があります。質問に特定の問題の詳細を提供していないため、この回答は非常に高レベルです。特定の問題を解決する方法の詳細が必要な場合は、完全なコンテキストを提供してください。誰かがあなたを助けることができると確信しています。

于 2012-10-10T04:24:20.753 に答える
1

これは本質的に難しい問題です。分散型ガベージの問題は、正しく解決することが不可能ではないにしても、非常に困難です。

ただし、Javaファイナライザーを使用してメソッドをオーバーライドするだけで機能する場合がありますfinalize()。次に、C++で説明したものと同様のメッセージング手法を実装できます。

これは、より一般的なケースで問題が発生し(アマロイが指摘するように、マシン間で循環参照を行うのに役立ちません)、注意すべき他のいくつかの癖があります(主に、ファイナライザーが呼び出されるタイミングを正確に制御できないことに関するものです)。 )ただし、特定の状況で機能させることができる場合があります。

于 2012-10-10T06:35:33.247 に答える
0

データ構造Aを内部のどこかに保持するためにrefやatomなどのデータ構造を使用していると仮定すると、リスナーを使用してその構造の状態を監視し、Aを削除できます。また、これらのリスナーは適切なメッセージをBに送信 clojure.data/diffできます。削除された構造を見つけるのに本当に便利です。

もう1つのオプションは、A構造体が逆参照された直後に、そのようにするための関数がメッセージを送信するようにすることです。ただし、この一環として、そのコードが実際にAの削除に関与しており、他の更新には関与していないことを確認してください。

于 2012-10-12T04:55:12.023 に答える