Go のファイナライズ: デフォルトのオブジェクトと落とし穴
Go では、ファイナライズとは、オブジェクトがガベージ コレクションされる前にオブジェクトに対してクリーンアップ アクションを実行するプロセスです。 。デフォルトでは、選択された数種類のオブジェクトのみがファイナライズされます。これには以下が含まれます:
ファイナライズはクリーンアップ アクションを実行する便利な方法ですが、潜在的な落とし穴もあります。このような問題の 1 つは、os.File が os.NewFile(fd int, name string) *File を使用して作成され、同じファイル記述子が別の os.File オブジェクトによって使用される場合に発生します。このシナリオでは、どちらかのファイル オブジェクトのガベージ コレクションにより、もう一方のオブジェクトが使用できなくなります。
たとえば、次のコードを考えてみましょう。
package main import ( "fmt" "os" "runtime" ) func open() { os.NewFile(1, "stdout") } func main() { open() // Force finalization of unreachable objects _ = make([]byte, 1e7) runtime.GC() _, err := fmt.Println("some text") // Print something via os.Stdout if err != nil { fmt.Fprintln(os.Stderr, "could not print the text") } }
このコードでは、「テキストを印刷できませんでした」と表示されます。 " これは、1 つの os.File オブジェクト (os.NewFile によって作成された) のガベージ コレクションによって、他の os.File オブジェクトでも使用されているファイル記述子が閉じられるためです。 (os.Stdout)。その結果、os.Stdout はその後の I/O 操作に使用できなくなります。
この落とし穴を回避するには、特に os.NewFile を使用する場合、ファイル記述子を注意深く管理することが重要です。あるいは、runtime.SetFinalizer 関数を使用してファイナライザーを nil に設定することで、os.File オブジェクトのファイナライゼーションを無効にすることもできます。
以上がGo のファイナライゼーション: 落とし穴とは何ですか?またその落とし穴はどうすれば回避できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。