ガベージコレクション

不要になったメモリを自動的に解放するランタイムの仕組み

メモリ管理ランタイム

ガベージコレクションとは

ガベージコレクション (GC) は、プログラムが使わなくなったメモリを自動的に検出・解放するランタイムの仕組みである。JavaScript (V8)、Java (JVM)、Go、Python が GC を持つ。Rust は GC の代わりに所有権システムでメモリを管理する。

GC あり vs GC なし

観点 GC あり (JS, Java, Go) GC なし (Rust, C)
メモリ管理 自動 手動 (Rust は所有権)
メモリリーク 起きにくい 起きやすい (C)
パフォーマンス GC 停止 (STW) がある 予測可能
開発速度 速い 遅い (メモリを意識)

V8 (Node.js) の GC

V8 は世代別 GC を採用している。

Young Generation (新世代):
  新しいオブジェクトを格納
  頻繁に GC (Scavenge) → 生き残ったオブジェクトは Old へ

Old Generation (旧世代):
  長寿命のオブジェクトを格納
  低頻度で GC (Mark-Sweep-Compact)
世代 GC アルゴリズム 頻度 停止時間
Young Scavenge (コピー GC) 高い 短い (1〜10ms)
Old Mark-Sweep-Compact 低い 長い (10〜100ms)

メモリリーク

GC があってもメモリリークは発生する。参照が残っている限り GC は回収しない。

// ❌ メモリリーク: イベントリスナーの解除忘れ
element.addEventListener('click', handler);
// element が削除されても handler が参照を保持 → GC されない

// ❌ メモリリーク: クロージャが大きなオブジェクトを保持
function createHandler() {
  const largeData = new Array(1000000); // 100万要素
  return () => console.log(largeData.length); // largeData への参照が残る
}

// ❌ メモリリーク: グローバル変数にデータを蓄積
const cache: Record<string, any> = {};
function addToCache(key: string, value: any) {
  cache[key] = value; // 際限なく増加
}

Lambda でのメモリ管理

Lambda の MemorySize 設定は GC の挙動に影響する。メモリが少ないと GC が頻繁に発生し、レイテンシが増加する。

メモリリークの検出

# Node.js のヒープスナップショット
node --inspect app.js
# Chrome DevTools → Memory → Heap Snapshot

Rust の所有権 (GC の代替)

{
    let s = String::from("hello"); // s がメモリを所有
    // s を使用
} // スコープを抜けると自動的にメモリ解放 (GC 不要)

理論と実装の両面から学ぶなら関連書籍が参考になる。

関連用語