Go でデータ構造を操作する際の一般的な懸念は、メモリ リークの可能性です。この質問は、ポインタのマップからエントリを削除するとそのようなリークが発生する可能性があるかどうかに焦点を当てています。
ドキュメントではこれに明示的に対処していませんが、Go ランタイム ソースの調査コードは、エントリがマップから削除されると、キーと値の両方のストレージがクリア (ゼロ化) されることを示しています。これは、中に含まれるポインタもクリアされることを意味します。
// Clear key storage. memclr(k, uintptr(t.keysize)) // Clear value storage. v := unsafe.Pointer(uintptr(unsafe.Pointer(b)) + dataOffset + bucketCnt*uintptr(t.keysize) + i*uintptr(t.valuesize)) memclr(v, uintptr(t.valuesize))
これを裏付けるために、ポインタのマップを含むサンプル プログラムを作成し、ファイナライザーを登録します。ポインターが到達不能になったときにキャッチします:
import ( "fmt" "runtime" "sync" "time" ) type point struct { X, Y int } func main() { // Create a map and put a pointer value in it, with a finalizer. m := map[int]*point{} p := &point{1, 2} runtime.SetFinalizer(p, func(p *point) { fmt.Printf("Finalized: %p %+v\n", p, p) }) m[1] = p fmt.Printf("Put in map: %p %+v\n", p, p) // Delete the entry from the map. delete(m, 1) // Force garbage collection. runtime.GC() // Sleep to ensure the finalizer has a chance to run. time.Sleep(time.Second) // Print the map to verify the map itself wasn't garbage collected. fmt.Println(m) }
これを実行すると、次の出力が生成されます:
Put in map: 0x1040a128 &{X:1 Y:2} Finalized: 0x1040a128 &{X:1 Y:2} map[]
ご覧のとおり、ポインターがマップから削除されるとファイナライザーが呼び出されます。到達不能になり、メモリ リークがないことがわかります。
以上がマップ エントリを削除すると、Go でメモリ リークが発生する可能性がありますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。