🐱 うさねこ教室 Python と可観測性の教室

GC とメモリ管理

🐱 この章の目次

ガベージコレクションの基本

Python は 参照カウント を主なメモリ管理手法とし、循環参照のために世代別 GC を補助的に使います。 JVM は参照カウントを使わず、トレーシング GC がヒープ全体を走査して不要なオブジェクトを回収します。 この設計の違いが、パフォーマンス特性とチューニングの必要性に大きな差を生みます。

ヒープの世代構造

JVM のヒープメモリは Young 世代Old 世代 に分かれています。 新しいオブジェクトは Young 世代に割り当てられ、短命なオブジェクトはここで素早く回収されます。 長く生存するオブジェクトは Old 世代に昇格し、低頻度で回収されます。

┌─────────────────────────────────────────┐
│              JVM ヒープ                   │
├──────────────────┬──────────────────────┤
│   Young 世代     │      Old 世代         │
│  (短命オブジェクト) │  (長命オブジェクト)    │
│  高頻度 GC       │  低頻度 GC            │
└──────────────────┴──────────────────────┘

GC アルゴリズムの選択

G1GC は JDK 9 以降のデフォルト GC で、レイテンシとスループットのバランスに優れています。 ZGC は JDK 21 で本番対応となった低レイテンシ GC で、最大停止時間を 1ms 未満に抑えます。 用途に応じて GC を選択できるのは、Python にはない JVM の柔軟性です。

# GC の選択(JVM 起動オプション)
java -XX:+UseG1GC -jar app.jar       # G1GC(デフォルト)
java -XX:+UseZGC -jar app.jar        # ZGC(低レイテンシ)

GC チューニングの基本

最低限押さえるべきオプションはヒープサイズの設定です。

java -Xms512m -Xmx2g -jar app.jar
#    初期ヒープ  最大ヒープ
オプション意味
-Xms初期ヒープサイズ
-Xmx最大ヒープサイズ
-XX:+UseG1GCG1GC を使用
-XX:MaxGCPauseMillis=200目標停止時間(ms)

Python との違い

Python ではメモリ管理を意識することはほとんどありません。 参照カウントがオブジェクトを即座に解放し、循環参照コレクタが残りを処理するためです。

JVM では GC の停止時間(Stop-the-World パーズ)がレスポンスタイムに影響するため、本番環境ではチューニングが重要です。 特にリアルタイム性が求められるサービスでは、GC の選択とヒープサイズの調整がパフォーマンスを左右します。