5

C ライブラリから Java (または、実行が保証されているデストラクタを持たない他のガベージ コレクション言語) へのバインドを行う場合、ガベージ コレクションされていないメモリの適切な割り当て解除をどのように処理しますか?

編集:私が考えているのは(これは私の元の質問で明示的に述べられていないことを知っています)、GCされていないメモリの一部が、解放する必要がある他のGCされていないリソースへの参照を保持しているときです。オブジェクトが解放されます。たとえば、そのようなノードの長いリストの先頭にある非 gc のリンク リスト ノードがあり、最終的に gc システムに自動的にクリーンアップさせたい場合、どのように設定しますか?

4

3 に答える 3

2

これらは通常、参照を作成およびリリースするための API を提供します。

たとえば、Java の Native Interface はグローバル参照を提供しており、C プログラムが Java オブジェクトをNewGlobalRefおよびDeleteGlobalRef

NewGlobalRefobj 引数によって参照されるオブジェクトへの新しいグローバル参照を作成します。obj 引数は、グローバル参照またはローカル参照の場合があります。グローバル参照は、呼び出して明示的に破棄する必要がありますDeleteGlobalRef()

また、Java が次の目的で制御を C に渡した場合にのみ存続するローカル参照も提供します。

ローカル参照は、ネイティブ メソッド呼び出しの間有効です。ネイティブ メソッドが返された後、それらは自動的に解放されます。

JVM 埋め込み APIは、C プログラムがオブジェクトの処理が完了したと判断するまで、オブジェクトをメモリに固定できる同様のメカニズムを提供します。

Python の C 拡張 APIは、JNI と同様の API を提供します。

借用参照は、 を呼び出して所有参照に変更できますPy_INCREF()

Py_DECREF()参照の所有者は、参照が不要になったときに呼び出す責任があります。

Python の名前は、Python が参照カウントを使用するという事実を反映しています* が、API は基本的に非参照カウント ガベージ コレクタに基づく JNI のものと同じです。インタプリタによって管理されるメモリ領域を固定する関数が 1 つあります。もう 1 つは、以前に固定された領域を解放してインタープリターに戻します。

* - python は、真の ref-counting アプローチではありません。同じページから「Python は従来の参照カウントの実装を使用していますが、参照サイクルを検出するために機能するサイクル検出器も提供しています。」

于 2011-08-03T17:11:32.220 に答える
2

Java では、finalize()の概念があります。そこで C メモリを解放できます。

ただし、おそらくより良い方法は、 ReferenceQueueと共にPhantomReferencesを使用することです。PhantomReference クラスを拡張して、解放する必要がある C 側のメモリへの ID やポインタなどを保持することができます。ReferenceQueue にエンキューされると、この ID が指す C 側のメモリを解放できます。Java オブジェクトは「Java 内」に存在しないことが保証されます。

于 2011-08-03T17:45:22.063 に答える
0

Java などの言語でバインディングを使用する場合、他の言語のマシンは、割り当てられた各オブジェクトの参照カウンターを保持します。API は、これらのカウンターを増減するメソッドを提供して、C プログラムが他のマシン オブジェクトへの参照を保持しているマシンを示す必要があります。C プログラムが特定のオブジェクトへの参照を持たない場合、参照カウンターが 0 に達する可能性があり、他の言語マシンはそれを自由にガベージ コレクションできます。ただし、特定のオブジェクトを解放するようマシンに要求できない場合があります。

于 2011-08-03T17:06:37.493 に答える