ガベージコレクション
もう使われないメモリを処理系が自動で見つけて回収する仕組み。手動管理の手間とバグを減らせますが、回収時の一時停止という代償もあります。
- 1.ガベージコレクション(GC)は到達不能になったメモリを自動で回収し、手動解放の手間を省きます。
- 2.代表手法は参照カウントとマークスイープで、それぞれ循環参照や停止時間に弱みがあります。
- 3.メモリリークやダングリングポインタを減らせる一方、回収中の一時停止(pause)が起こり得ます。
ガベージコレクションとは
プログラムは実行中にメモリ(主にヒープ)を確保しますが、使い終わったメモリは返さないと枯渇します。**ガベージコレクション(GC)**は、もう使われない=どこからも参照されないメモリを処理系が自動的に見つけて回収する仕組みです。
- 解放を書かなくてよい —
freeやdeleteを手で呼ぶ必要がなく、書き忘れによるリークが減ります。 - 不正アクセスを防ぎやすい — 解放済みメモリを誤って使う事故(後述のダングリングポインタ)が起きにくくなります。
- Java、C#、JavaScript、Python、Go など多くの主要言語が標準で備えています。
GC の判断基準は「使用中か」ではなく「到達可能か」。ルート(実行中の変数など)からたどり着けないオブジェクトを「ごみ」とみなします。
主なアルゴリズム
代表的な2方式を押さえると、GC の挙動を理解しやすくなります。
| 方式 | 仕組み | 弱点 |
|---|---|---|
| 参照カウント | 参照される数を数え、0になった瞬間に解放 | 循環参照を回収できない |
| マークスイープ | ルートから到達可能を印付け→未到達を一括回収 | 回収時に一時停止が出やすい |
参照カウントは即座に回収でき分かりやすい反面、互いに参照し合う循環参照(A→B→A)はカウントが0にならず残ります。マークスイープは循環も正しく回収できますが、走査のために処理を止める瞬間が生じます。実際の処理系は両者を組み合わせることもあります(例: 参照カウント+循環回収)。
世代別GCという改良
多くのオブジェクトは「作られてすぐ捨てられる」という経験則(世代仮説)があります。これを利用したのが世代別GCです。新しい世代を頻繁・小さく回収し、生き残った長寿命オブジェクトはたまにしか調べません。
- 若い世代 — 頻繁に回収。短命オブジェクトの大半をここで処理。
- 古い世代 — 長く生きたものを置く。回収は低頻度。
これにより、毎回ヒープ全体を走査するより停止時間を短く抑えられます。Java や .NET の GC はこの考え方を採用しています。
GC があっても到達可能なら回収されません。グローバルな配列やキャッシュ、解除し忘れたイベントリスナーが参照を握り続けると、メモリは増え続けます。「使わなくなったら参照を切る(null 代入や登録解除)」を意識しましょう。
利点と「停止」という副作用
GC の最大の利点は安全性と生産性ですが、自動である以上、回収のタイミングを処理系が握ります。これが**一時停止(pause / stop-the-world)**として表面化します。
[アプリ実行] → [GC開始:一瞬アプリ停止] → [回収] → [アプリ再開]
- 停止が長いと、UIのカクつきやリクエストの遅延として現れます。
- 近年のGCは停止を短く分散させる工夫(並行・インクリメンタル回収)を進めていますが、ゼロにはなりません。
- 「いつ回収されるか」を正確に制御しにくい点も、リアルタイム性が重要な領域では課題になります。
GC は「メモリを一切気にしなくてよい」ことを意味しません。大量・短命なオブジェクトを作り続けると回収頻度が上がり、停止が増えます。不要なオブジェクト生成を減らすことは、GC 言語でも有効な最適化です。
手動管理との対比
C / C++ のように手動でメモリを管理する言語と比べると、トレードオフが見えてきます。
| 観点 | 手動管理(C/C++) | ガベージコレクション |
|---|---|---|
| 解放 | プログラマが明示的に行う | 処理系が自動で行う |
| 主なリスク | リーク・二重解放・ダングリング | 回収時の一時停止 |
| 実行の予測性 | 制御しやすい(停止が読める) | 回収タイミングが読みにくい |
| 生産性 | 手間が多い | 高い |
なお Rust のように、GC を使わず所有権モデルでコンパイル時に解放を保証する方式もあり、両者の中間的な選択肢として注目されています。
まとめ
ガベージコレクションは、到達不能になったメモリを処理系が自動回収する仕組みで、リークや解放済みメモリへのアクセスといった手動管理の典型バグを大幅に減らします。代表手法は参照カウント(循環に弱い)とマークスイープ(停止が出やすい)で、世代別GCが停止時間の短縮に貢献します。利点は大きい一方、一時停止という副作用と「いつ回収されるか読みにくい」性質は理解しておくべきポイントです。
プログラミング Article
ガベージコレクションを実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
ガベージコレクション
比較で見る軸
難易度: intermediate / カテゴリ: プログラミング / タグ数: 3
導入後に効く点
代表手法は参照カウントとマークスイープで、それぞれ循環参照や停止時間に弱みがあります。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- intermediate
- カテゴリ
- プログラミング
- タグ数
- 3
判断チェックリスト
- 自社の用途が「ガベージコレクション / メモリ管理」に近いか確認する。
- 強みである「ガベージコレクション(GC)は到達不能になったメモリを自動で回収し、手動解放の手間を省きます。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。