Go スライスのメモリ リークについて
Go でスライスを操作する場合、特にポインタの場合にメモリ リークの可能性を理解することが不可欠です。
によるメモリ リークポインター
整数へのポインターのスライス ([]*int):
s := []*int{new(int), new(int)}
このスライスには長さ 2 のバッキング配列があり、非 nil が 2 つ含まれています配列の外に割り当てられた整数を指すポインタ。
ここで、スライスし直すとit:
s = s[:1]
長さは 1 になりますが、バッキング配列は変更されません。 2 番目の要素の未使用のポインターは、配列の一部としてメモリ内にまだ残っています。どのスライスからも参照されていないため、アクセスできなくなり、ガベージ コレクターによって解放できなくなり、メモリ リークが発生します。
なぜ非ポインターではないのですか?
非ポインターのスライス ([]int) の場合:
t := []int{1, 2}
スライスすると要素が非表示になります。新しいスライスから削除されますが、バッキング配列には残ります。ポインタとは異なり、これらの要素は配列自体の一部であり、外部メモリを参照しません。
ポインタと構造体
スライスがポインタを含む構造体を保持すると、メモリ リークが発生します。
type Books struct { title string author string } ... var bkSlice = []Books{Book1, Book2} bkSlice = bkSlice[:1]
スライスが Book1 のみを保持している場合でも、Book2 の著者とタイトルの文字列が発生する可能性があります。配列の一部としてメモリ内に残っています。これを防ぐには、スライスする前に Book2 にゼロ値を割り当てます。
bkSlice[1] = Book{} bkSlice = bkSlice[:1]
これにより、Book2 の文字列への参照が削除され、ガベージ コレクションが可能になります。
一般規則
メモリ リークを回避するには、スライスのバッキングの外側のメモリを参照する要素をゼロにすることを目指します。 配列。たとえば、ポインタ、スライス、またはその他の複雑なデータ構造であるフィールドを持つ構造体は、外部参照を遮断するために再スライスする前にゼロ化する必要があります。
以上がポインタを使用して Go スライスを再スライスするときにメモリ リークを回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。