ホームページ > バックエンド開発 > Golang > ポインタを使用して Go スライスを再スライスするときにメモリ リークを回避するにはどうすればよいですか?

ポインタを使用して Go スライスを再スライスするときにメモリ リークを回避するにはどうすればよいですか?

Patricia Arquette
リリース: 2024-11-26 03:08:13
オリジナル
807 人が閲覧しました

How Can I Avoid Memory Leaks When Reslicing Go Slices with Pointers?

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 サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート