ガベージコレクタによってクラスインスタンスが収集されるたびにfinalize()が呼び出されることはわかっています。しかし、私は、クラスのインスタンスをキュー経由で別のスレッドに渡すときにちょっと混乱します。このシナリオでは、クラスインスタンスでfinalize()が呼び出されるのはいつですか?
のは、これはスレッド1のスケルトンであるとしましょう:
for(i=0; i<1000; i++) {
Packet pkt = new Packet(); // instance of class
pkt.id = i;
thread2.queue.put(pkt);
}
次に、スレッド2はキューからパケットを削除し、長時間の操作を実行します。この2番目のスレッドは、パケットの「コピー」を取得するのか、それとも何らかの形式で参照するのでしょうか?重要なのは、コピーであれば、スレッド1で作成されたインスタンスのfinalize()は、スレッド2がパケットで完了する前に呼び出すことができるということです。参照の場合は、パケット内の情報に対してfinalize()が1回だけ呼び出されることが保証されています。
この基本的な例は重要性を示していないかもしれませんが、私はオブジェクトで終わったときにいくつかのメモリを破壊するためにパケットにCポインタ(JNIから)を格納しています。コピーによって渡された場合、メモリは、2番目のスレッドが処理を行う前に破壊される可能性があります。参照渡しの場合は、GCが両方のスレッドで使用されていないと判断した場合にのみ破棄する必要があります(私の希望する動作)。この後者のシナリオが保証されていない場合、私はfinalize()を使用せず、何か他のものを使用しますが、もっと複雑になります。
javaメソッドの引数との最も近いC/++の比較は、それらが値渡しのポインタであることです。だからそれはコピーであるが、ポインタのコピーだけである。 (誰の操作でも参照を外すだけです)システムのどこかにオブジェクトの場所を指すポインタが1つある限り、その場所は収集されません。 – Affe
C-ポインタをクリーンアップし、finalizeメソッドに依存しないか、ファイナライズメソッド –