Menu
Coddy logo textTech

Goのガベージコレクション

CoddyのGOジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 23/107。

CやC++などの言語とは異なり、Goはガベージコレクション(GC)によってメモリ管理を自動的に行います。使い終わったメモリを手動で解放する必要はありません。Goランタイムは、まだ使用中のメモリを追跡し、残りを再利用します。

new()make()を使用してメモリを割り当てたり、変数を作成したりすると、Goのガベージコレクターがこれらの割り当てを監視します。値がプログラムのどの部分からも到達できなくなると、GCはそのメモリを自動的に解放します。

func createPerson() *Person {
    p := &Person{Name: "Alice", Age: 30}
    return p  // p はヒープにエスケープし、GC が管理します
}

func main() {
    person := createPerson()
    fmt.Println(person.Name)
    // person が使用されなくなったとき、GC がメモリを回収します
}

この例では、Person 構造体は関数から返されるため、ヒープ上に割り当てられます。Go のコンパイラはエスケープ解析を実行して、変数をスタック上に保持できるか、ヒープに移す必要があるかを判断します。ガベージコレクターはヒープメモリのみを管理します。

この自動 memory 管理により、忘れられた解放による memory リークを心配せずに、アプリケーションの構築に集中できます。ただし、GC が存在することを理解しておくと、パフォーマンスが重要な場合に不要な割り当てを最小限に抑え、より効率的なコードを書くのに役立ちます。

challenge icon

チャレンジ

簡単

Goのガベージコレクターがヒープに逃避するオブジェクトのメモリをどのように扱うかを示すセッションマネージャーを構築しましょう。動的に割り当てられて関数から返されるセッションを作成し、GCにそのライフサイクルを管理させます。

コードを2つのファイルに分けて整理します。

  • session.go: ID(string)、Username(string)、Data(文字列のスライス)fieldsを持つSession structをDefineします。IDとusernameを受け取り、ヒープ上に新しいSessionを割り当て(pointerを返すことで)、Dataスライスをemptyとして初期化するNewSession functionをCreateします。また、pointer receiverを持ち、文字列をsessionのDataスライスにappendsするAddData methodと、sessionのdetailsを示すformatted stringを返すSummary methodも追加します。
  • main.go: inputからsession informationを読み取り、constructor functionを使用してsessionをCreateし、いくつかのdata entriesを追加して、session summaryを表示します。sessionはfunction内でCreateされてpointerとして返されるため、heapにescapeし、そこでgarbage collectorが管理します。

次のinputが提供されます。

  • 1行目: Session ID
  • 2行目: Username
  • 3行目: 追加する最初のdata entry
  • 4行目: 追加する2番目のdata entry

あなたのSummary methodは、次のformatのstringを返す必要があります。

Session [ID] for user [Username]
Data entries: [count]
- [entry1]
- [entry2]

たとえば、sess-001aliceloginview_dashboardが与えられた場合、outputは次のようになります。

Session sess-001 for user alice
Data entries: 2
- login
- view_dashboard

ここでの重要なポイントは、NewSession functionがSessionをCreateし、それへのpointerを返すことです。これにより、Sessionはstack上に留まるのではなく、ヒープに"escape"します。そのため、Sessionへの参照がなくなるとgarbage collectionの対象になります。このmemoryを手動でfreeする必要はありません。Goがautomatically処理します。

自分で試してみよう

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	reader := bufio.NewReader(os.Stdin)

	// セッションIDを読み取る
	sessionID, _ := reader.ReadString('\n')
	sessionID = sessionID[:len(sessionID)-1]

	// ユーザー名を読み取る
	username, _ := reader.ReadString('\n')
	username = username[:len(username)-1]

	// 最初のデータエントリを読み取る
	data1, _ := reader.ReadString('\n')
	data1 = data1[:len(data1)-1]

	// 2番目のデータエントリを読み取る
	data2, _ := reader.ReadString('\n')
	data2 = data2[:len(data2)-1]

	// TODO: NewSession関数を使用して新しいセッションを作成する
	// ポインタを返すため、セッションはヒープにエスケープする

	// TODO: AddDataメソッドを使用してデータエントリをセッションに追加する

	// TODO: Summaryメソッドを使用してセッションの概要を出力する
	fmt.Println("")
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Goオンラインコンパイラ