LoginSignup
0
0

Go言語とメモリ: 確保と保存の理解

Last updated at Posted at 2023-06-09

はじめに

Go言語の学習中にメモリについてつまづきました。そのことについて整理するためにこの記事を投稿します。この記事では、Go言語でのメモリの「確保」と「保存」に焦点を当てます。

メモリについて意識する場面とは

例えばjson.Unmarshaljson.Marshal関数かjson.NewDecoderjson.NewEncoder関数のどちらを使用するかについてです。json.Unmarshaljson.Marshalは、メモリにすでに全体が読み込まれているJSONデータを処理する際に適しています。これは、JSONのサイズが小さく、一度に全てのデータをメモリに読み込むことができる場合に限られます。例えば、APIからのレスポンスや小さな設定ファイルなどが該当します。一方、json.NewDecoderjson.NewEncoderは、大きなサイズのJSONデータやストリーム型のデータを扱う場合に適しています。これらの関数は、データを逐次的に処理できます。これは大きなデータファイル(数GBものJSONデータ)や、リアルタイムで更新されるデータ(ソケットからのストリーミングデータなど)を扱う際に重要です。

1. メモリ領域の確保と保存の違い

メモリの「確保」は、ある種のデータを格納するためのメモリ領域を準備することを意味します。一方、「保存」は、特定の値をメモリ上に記録することを指します。

Go言語では、変数を宣言することでメモリ領域が確保されます。例えば以下です。

var myInt int

このコードは、整数を保存するためのメモリ領域を確保し、myIntという名前をつけます。この時点では、myIntにはゼロ値である0が自動的に保存されます。ですので,変数の宣言だけで初期化をしていない場合でも最終的には各型のゼロ値が自動的に保存されます。

2. メモリに確保と保存がされるときと確保と保存がされない時のパターン

変数の宣言と初期化はメモリの確保と保存の一般的なパターンです。

var i int = 10

ここでは、iという名前のメモリ領域が確保され、値10がその領域に保存されます。

また、Goの構造体や配列などの複合データ型も同様です。以下の例では、Personという型の変数pが作成され、それぞれのフィールドに値が保存されます。

type Person struct {
    Name string
    Age  int
}
p := Person{Name: "Alice", Age: 30}

ただし、型を定義するだけではメモリは確保されません。

type WeatherResponse struct {
	Main struct {
		Temp float64 `json:"temp"`
	} `json:"main"`
	Weather []struct {
		Description string `json:"description"`
	} `json:"weather"`
}

このWeatherResponse型を実際に使うまで、メモリ領域は確保されません。

3. 関数とメモリ

関数が呼び出されるとき、その引数とローカル変数はメモリ(具体的にはスタック)に保存されます。関数が終了すると、そのスタックフレームは解放され、引数とローカル変数はメモリから消去されます。

func add(a int, b int) int {
    var sum = a + b
    return sum
}

関数addが呼び出されると、引数ab、そしてローカル変数sumのためのメモリ領域が確保されます。関数が終了した後、これらの領域は解放されます。

まとめ

Go言語のメモリ管理は、効率的なプログラムの設計において重要な役割を果たします。メモリの確保と保存の違いを理解し、それらがいつ発生するのかを知ることで、Go言語の動作についてより深く理解することができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0