次のように、Go構造体でラップされたC型へのポインタがあります。
type Wrapper struct {
unmanaged *C.my_c_type
}
次に、Cタイプには次の機能があります。
my_c_type* make_c_type();
void free_c_type(my_c_type *ct);
インスタンスがファイナライズfree_c_type
されるたびに呼び出されるようにする方法はありますか?Wrapper
次のように、Go構造体でラップされたC型へのポインタがあります。
type Wrapper struct {
unmanaged *C.my_c_type
}
次に、Cタイプには次の機能があります。
my_c_type* make_c_type();
void free_c_type(my_c_type *ct);
インスタンスがファイナライズfree_c_type
されるたびに呼び出されるようにする方法はありますか?Wrapper
runtime.SetFinalizerを使用できます。これにより、オブジェクトがスコープから外れたときにクリーンアップ関数を実行できます。実行は保証されません。ただし、メモリを解放する場合、それは実際には重要ではありません。重要なのは、長時間実行されるプロセスでは、ガベージを抑制し続ける可能性が高いということです。
ドキュメントからの抜粋を次に示します(段落全体が削除されました)。
SetFinalizerは、xに関連付けられたファイナライザーをfに設定します。ガベージコレクターは、ファイナライザーが関連付けられた到達不能ブロックを検出すると、関連付けをクリアし、別のゴルーチンでf(x)を実行します。これにより、xが再び到達可能になりますが、ファイナライザーが関連付けられなくなります。SetFinalizerが再度呼び出されないと仮定すると、次にガベージコレクターがxに到達できないことを確認すると、xが解放されます。
xのファイナライザーは、xが到達不能になった後の任意の時間に実行されるようにスケジュールされています。ファイナライザーは、プログラムが終了する前に実行される保証はありません。したがって、通常、ファイナライザーは、長時間実行されるプログラム中にオブジェクトに関連付けられた非メモリーリソースを解放する場合にのみ役立ちます。たとえば、os.Fileオブジェクトは、プログラムがCloseを呼び出さずにos.Fileを破棄したときに、ファイナライザーを使用して関連するオペレーティングシステムファイル記述子を閉じることができますが、メモリ内のフラッシュをファイナライザーに依存するのは間違いです。 / Oバッファー(bufio.Writerなど)。プログラムの終了時にバッファーがフラッシュされないためです。
1つのゴルーチンが、プログラムのすべてのファイナライザーを順番に実行します。ファイナライザーを長時間実行する必要がある場合は、新しいゴルーチンを開始して実行する必要があります。