Go は自動的にメモリを管理し、ガベージコレクタによって手動の割り当て/解放から解放されます。GC は並行実行型、低遅延、世代別でない mark-and-sweepコレクタであり、ポーズ時間を最小化するように設計されています。これは Go が遅延時間に敏感なサービスに適している重要な理由です。
スタック対ヒープとエスケープ解析
{
x :=
x
}
* {
x :=
&x
}
Go のコンパイラはエスケープ解析をコンパイル時に実行します。関数の存続期間より長く生存しない値は、低コストで自動的に解放されるスタックに配置されます。参照がエスケープする値はヒープに配置され(GC がこれを管理します)、スタック割り当ては本質的に無料なため、ヒープエスケープを最小化することで GC の作業を削減します。
Go's GC characteristics:
✓ MARK-AND-SWEEP — marks reachable objects (from roots), sweeps the rest
✓ CONCURRENT — runs mostly alongside your program (not stop-the-world)
✓ LOW LATENCY — optimized for short pauses (typically sub-millisecond), not throughput
✓ NON-GENERATIONAL — unlike the JVM, treats all objects uniformly (simpler)
Go は意図的に低いポーズ時間を生のスループットよりも優先します。GC はプログラムと並行してほとんどの作業を行い、「stop-the-world」ポーズを非常に短く保ちます。これにより、Go は遅延時間に敏感なサーバーに適しています。
GOGC=100 # default: trigger GC when heap grows 100% since the last collection
# higher GOGC → less frequent GC (more memory, less CPU)
# lower GOGC → more frequent GC (less memory, more CPU)
GOMEMLIMIT=2GiB # a soft memory limit (Go 1.19+) — GC works harder near it
// 1. reuse objects with sync.Pool to reduce allocations
var bufPool = sync.Pool{New: func() any { return new(bytes.Buffer) }}
buf := bufPool.Get().(*bytes.Buffer)
defer bufPool.Put(buf)
// 2. preallocate slices with known capacity (avoid repeated growth/realloc)
data := make([]int, 0, 1000)
// 3. minimize heap escapes; avoid unnecessary pointers/allocations in hot loops
割り当てが少ないほど GC の作業が少なくなります。sync.Pool(オブジェクト再利用)、事前割り当て、エスケープの最小化がホットパスで GC 負荷を軽減する主な方法です。
GC frees only UNREACHABLE objects. Leaks come from lingering REFERENCES:
✗ goroutine leaks (a blocked goroutine keeps its referenced memory alive)
✗ growing global maps/slices, unclosed resources, forgotten subscriptions
Go の自動メモリ管理は生産性と安全性の大きなメリット(手動解放なし、dangling ポインタなし)ですが、どのように動作するかを理解することは、パフォーマンス重視の遅延時間に敏感なアプリケーション(Go が選ばれることが多い)に対して価値があります。
主な洞察:エスケープ解析はスタック対ヒープ割り当てを決定し(スタックは無料で、ヒープエスケープを最小化すると GC 作業が削減される)、Go の並行実行型、低遅延 GCはスループット(スループット重視のコレクタとは異なり、サーバーに最適)よりもショートポーズを優先します。
GC 負荷を軽減する方法(sync.Pool、事前割り当て、ホットループ内の割り当て削減)、GC をチューニングする方法(GOGC、GOMEMLIMIT)、およびリークはなお発生することを認識すること(特にゴルーチンリーク)は、高パフォーマンスの Go サービスを運用する上で重要です。
これはシニア Go 開発者を区別し、パフォーマンス重視の職種の一般的な高度なインタビュー トピックである深い実践的な知識です。
ジュニアからシニアまで、詳細な回答付きのIT面接質問ライブラリ。
寄付する