JavaのGC(Garbage Collection)とは?仕組みと注意点

GCとは何か

Java で開発をしていると、よく耳にする「GC(Garbage Collection)」。
これは 不要になったオブジェクトを自動で回収してメモリを解放する仕組み のことです。C言語のように手動で free() を呼ぶ必要はなく、Java VM が裏側でメモリ管理を行います。

 

ざっくり構造・最近のGC

  • 世代別回収:Eden/Survivor(若世代)→ Old(老世代)

  • Minor GC:Edenが埋まったら短命オブジェクト中心に回収

  • Major/Full GC:Oldが逼迫、断片化、クラス/メタ領域逼迫などで広域回収

  • 既定GC:G1GC(Java 9+)。低停止要求は ZGC / Shenandoah も選択肢

主なトリガ

  • Eden満杯(Minor) / Old高水準(Major)

  • 巨大配列(Humongous)割当て(G1)

  • System.gc() 明示呼び出し

  • メタスペース/オフヒープ圧迫(DirectByteBuffer/JNI など)


“悪い例 → 良い例”で学ぶメモリ/GC対策

1) 無制限キャッシュ(静的Map地獄)

悪い例

良い例(上限+期限+統計)

ポイント:上限なしは必ずOldを膨らませる。キャッシュは 容量・期限・エビクションを設計。


2) リスナ/コールバック未解除

悪い例

良い例(ライフサイクルで必ず解除 / AutoCloseable化)

補足WeakReference リスナはイベント強度低下意図せぬ解放のリスク。基本は明示解除


3) ThreadLocal の放置(プールスレッドに張り付く)

悪い例

良い例(finallyで確実に除去)

ポイントスレッドプール=長寿命remove() を忘れると実質グローバル保持


4) System.gc() 乱用

悪い例

良い例


5) ラムダ/内部クラスが外側(巨大オブジェクト)をキャプチャ

悪い例

良い例(必要最小限のデータだけ渡す・static化)

ポイントキャプチャ=保持。意図せず大物を延命していないか疑う。


6) ループ内の大量一時オブジェクト

悪い例

良い例(StringBuilder再利用・ボクシング回避)


7) finalize/Cleaner頼み(遅延・不確実)

悪い例

良い例(確実な即時解放) 


8) クラスローダ・アプリ再デプロイ時のリーク

悪い例

良い例(クラスローダ境界を越える参照を断つ)

 

9) 巨大配列・Humongous割当ての長期保持(G1)

悪い例

良い例(分割・ストリーミング・寿命短縮)

ポイント:巨大ブロックは断片化回収コスト増の温床。


10) 無制限のキュー/バッファ

悪い例

良い例(有界+バックプレッシャ)


GCログ・計測の始め方(JDK 9+)

  • まずはコードの割当て削減 → その後にヒープ/GC調整

  • 監視:jcmd <pid> GC.heap_info / jstat -gc <pid> 1000

  • ボトルネック特定:JFR(Java Flight Recorder) で割当てホットスポットを把握

  • 必要なら ZGC/Shenandoah も評価(レイテンシ目標に応じて)


実務チェックリスト(配布推奨)

  1. System.gc() を禁止/抑制

  2. キャッシュ・キューは有界+期限

  3. ThreadLocal は finally で remove

  4. リスナ/コールバックは確実に解除(AutoCloseable化が効く)

  5. ループ内の一時オブジェクトを減らす(Builder再利用/ボクシング回避)

  6. 巨大配列は分割・短命化

  7. クラスローダ境界を跨ぐ静的参照禁止、Executor停止・ドライバ解除

  8. try-with-resourcesでオフヒープ即時解放

  9. GCログ/JFRで事実ベースに調整

  10. 目標停止時間(例:MaxGCPauseMillis)を定めて検証


まとめ

GCは“自動”でも“万能”ではありません。
「GCが働きやすいコード」(不要参照を残さない・波及して大物を掴ませない・ピークメモリを避ける)を心がけ、ログ/計測で改善ループを回すのが最短距離です。

Git と SVN の違いを徹底比較!モダン開発と Git 移行メリットを解説

ソフトウェア開発では欠かせないバージョン管理システム(VCS)。
代表的なものに Subversion(SVN)Git がありますが、それぞれ仕組みや特徴に大きな違いがあります。
この記事では両者を比較し、どんな場面で使われるのかを整理していきます。


1. 管理方式の違い

  • SVN は中央サーバー型(集中管理型)。サーバーに履歴があり、各開発者は必要な部分をチェックアウトして作業します。

  • Git は分散型。各開発者の手元に完全な履歴がコピーされるので、オフラインでもコミットや履歴の参照が可能です。


2. ブランチの扱い

  • SVN:ブランチはディレクトリをコピーする仕組み。重いため頻繁に切り替える運用には向きません。

  • Git:ブランチはポインタのような軽量な仕組み。気軽に作成・切り替え・統合でき、アジャイル開発と相性が良いです。


3. 比較表

項目SVN(Subversion)Git
管理方式集中型(中央リポジトリ必須)分散型(ローカルに完全コピー)
履歴サーバーに依存・オフライン不可ローカルに全履歴あり・オフライン可能
ブランチディレクトリコピーで重い軽量で高速・並行開発に最適
操作速度サーバー通信が多く遅めローカル主体で非常に速い
権限管理ディレクトリ単位で詳細設定可リポジトリ単位(サービス連携で補完)
使われ方レガシー環境・金融/公共系で根強いオープンソース・モダン開発の標準
 

4. 企業で SVN が残る理由

  • レガシー資産が膨大:10年以上運用しているプロジェクトを変えるコストが大きい

  • 単純な運用ルール:常に「中央が正」でシンプル

  • アクセス制御が細かい:サーバーで一元管理しやすい

  • 情報漏洩リスクを嫌う:ローカルに履歴を残さないことで安心とされるケースもある


5. Git への移行メリット

  • 効率的な並行開発:ブランチが軽いので複数人開発でもストレスが少ない

  • オフライン作業可能:出張先やネットが不安定でも履歴参照やコミットができる

  • エコシステムが豊富:GitHub・GitLab・Bitbucket など連携サービスが充実

  • CI/CD と相性抜群:自動テスト・デプロイと組み合わせやすい


まとめ

  • SVN は「安定・単純・集中管理」が強みで、金融や公共系、レガシー環境で今も利用されています。

  • Git は「柔軟・高速・モダンツール連携」が強みで、オープンソースやアジャイル開発での標準です。

👉 新規プロジェクトであれば Git を選ぶのが一般的。
ただし既存の大規模システムでは「SVN を参照専用にして、新規は Git」で併用するケースもよくあります。