{}const=>[]async()letfn</>var
開発実践

JVMの最適化:30分で遅いアプリケーションから本番環境へ

この詳細なガイドでは、JVMを正しく設定し、ガベージコレクターを選択し、アプリケーションをプロファイリングし、実際の負荷に備える方法について説明します。実践例、既成の構成、および本番環境のチェックリストは、初心者の開発者に必要なものすべてです。

К

Kodik

著者

2分で読める

JVMメモリの構造:ヒープを理解する

ヒープは、アプリケーションのすべてのオブジェクトが格納されるメモリ領域です。これは、いくつかの領域に分かれています。

ヒープの構造:

若い世代:

  • Eden Space — ここでは新しいオブジェクトが作成されます

  • Survivor Space (S0 と S1) — 最初のゴミ収集を乗り越えたオブジェクト

Old Generation (旧世代):

  • 複数のガベージコレクションサイクルを生き延びた長寿命オブジェクト

Metaspace (Java 8+のPermGenに代わる):

  • クラスのメタデータ、定数

ヒープのサイズを設定する方法

# 最小および最大ヒープサイズを設定する
java -Xms2g -Xmx4g -jar myapp.jar

# -Xms — 初期ヒープサイズ (2 GB)
# -Xmx — 最大ヒープサイズ (4 GB)

重要なルール: XmsXmx は、実行中にヒープのサイズが変わらないように、本番環境では同じサイズにすることをお勧めします。

必要なサイズを計算する方法は?

まずは次の式を使用します。

Heap Size = (Peak Live Data Size) × (2-4)

Peak Live Data Sizeは、Full GC後の「ライブ」オブジェクトの最大量です。

🔥 10万人以上の学生が参加中

理論を読むのに疲れた?
コーディングの時間だ!

Kodik — 実践でプログラミングを学ぶアプリ。AIメンター、インタラクティブなレッスン、実際のプロジェクト。

🤖 AI 24時間
🎓 修了証
💰 無料
🚀 始める
今日参加

ガベージコレクション:選択と設定

GC(ガベージコレクター)は、使用していないオブジェクトをメモリから自動的に削除します。ガベージコレクターにはいくつかの種類があり、それぞれに独自の特徴があります。

GCの主な種類:

1.シリアルGC (小規模アプリケーション向け)

java -XX:+UseSerialGC -jar myapp.jar

使用するタイミング: 単一スレッドアプリケーション、ヒープ < 100 MB

2. Parallel GC(Java 8のデフォルト)

java -XX:+UseParallelGC -jar myapp.jar

使用するタイミング: スループットが重要なアプリケーションでは、一時停止を許容できます

3. G1GC(ほとんどの場合に推奨)

java -XX:+UseG1GC -jar myapp.jar

使用するタイミング: ヒープが4GBを超える場合、予測可能な一時停止が必要

一時停止の目標時間を設定するには:

java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar myapp.jar

4. ZGCとShenandoah(低レイテンシーアプリケーション向け)

# ZGC(Java 11+、Java 15で本番環境対応)
java -XX:+UseZGC -jar myapp.jar

# Shenandoah
java -XX:+UseShenandoahGC -jar myapp.jar

使用するタイミング: 最小ポーズ(<10 ms)、大きなヒープが重要です

ログでのGCの監視

詳細なGCログを有効にします。

java -Xlog:gc*:file=gc.log:time,uptime:filecount=5,filesize=100m \
     -XX:+UseG1GC \
     -jar myapp.jar

プロファイリング:ボトルネックを見つける

プロファイリングは、アプリケーションが時間とメモリをどこで消費しているかを理解するのに役立ちます。

1. JVisualVMを使用する(無料)

JVisualVMはJDKに含まれており、次のことができます。

  • CPUとメモリの使用状況をリアルタイムで監視する

  • ヒープダンプを撮影する

  • フローを分析する

# JMXでアプリケーションを起動する
java -Dcom.sun.management.jmxremote \
     -Dcom.sun.management.jmxremote.port=9010 \
     -Dcom.sun.management.jmxremote.authenticate=false \
     -Dcom.sun.management.jmxremote.ssl=false \
     -jar myapp.jar

次に、VisualVMを介してlocalhost:9010に接続します。

2. ヒープダンプの分析

OutOfMemoryErrorが発生した場合は、メモリのスナップショットを取得すると便利です。

# OOM時の自動ダンプ
java -XX:+HeapDumpOnOutOfMemoryError \
     -XX:HeapDumpPath=/tmp/heapdump.hprof \
     -jar myapp.jar

# または手動で作成する
jmap -dump:live,format=b,file=heap.bin <PID>

Eclipse MATまたはVisualVMでダンプを分析し、次のものを探します。

  • 最も多くのメモリを占有するオブジェクト

  • メモリリーク

  • 予想外の大規模コレクション

3. Async Profiler (production-ready)

プロダクションには、アプリケーションの速度を低下させない async-profiler が適しています。

# ダウンロード
wget https://github.com/jvm-profiling-tools/async-profiler/releases/latest/download/async-profiler-2.9-linux-x64.tar.gz

# 60秒間プロファイリングを実行する
./profiler.sh -d 60 -f flamegraph.html <PID>

結果は、フレームグラフで、「ホット」メソッドが表示されます。

4. メトリックのモニタリング

Micrometer + Prometheus + Grafanaを使用します。

// Spring Boot は JVM メトリクスを自動的にエクスポートします
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

application.propertiesに次を追加します。

management.endpoints.web.exposure.include=prometheus,health,metrics
management.metrics.export.prometheus.enabled=true

典型的な問題とその解決策

問題1:頻繁なFull GC

症状: アプリが数秒間「フリーズ」する

解決策:

# ヒープを増やすか、ヤングジェネレーションを設定してください
java -Xms4g -Xmx4g \
     -XX:NewRatio=2 \
     -XX:+UseG1GC \
     -jar myapp.jar

問題2:OutOfMemoryError:Javaヒープスペース

解決策:

  1. -Xmxを拡大する

  2. ヒープダンプを介してメモリリークを見つける

  3. コードを最適化する(不要なコレクションを削除する)

問題3:OutOfMemoryError:メタスペース

解決策:

# メタスペースを拡大する
java -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -jar myapp.jar

問題 4:GC による高い CPU 使用率

解決策:

  • より効率的なGC(G1、ZGC)に切り替えます

  • ヒープを増やす

  • コード内のオブジェクトの作成を最適化する

プロダクション準備チェックリスト

1. メモリ設定

java -Xms4g -Xmx4g \                    # 固定ヒープ
     -XX:MetaspaceSize=256m \           # Metaspace
     -XX:MaxMetaspaceSize=512m \
     -XX:+UseG1GC \                     # G1 GC
     -XX:MaxGCPauseMillis=200 \         # 一時停止の目標時間
     -XX:+HeapDumpOnOutOfMemoryError \  # OOM でのダンプ
     -XX:HeapDumpPath=/var/log/app \
     -jar myapp.jar

2. GCのログ

-Xlog:gc*:file=/var/log/app/gc.log:time,uptime:filecount=5,filesize=100m

3. 監視のためのJMX

-Dcom.sun.management.jmxremote \
-Dcom.sun.management.jmxremote.port=9010 \
-Dcom.sun.management.jmxremote.authenticate=true \
-Dcom.sun.management.jmxremote.ssl=true \
-Dcom.sun.management.jmxremote.password.file=/etc/jmx.password

4. コンテナ化(Docker)

JVMは、Java 10以降のコンテナの制限を自動的に検出します。

FROM openjdk:17-slim

# JVMは自動的に制限を表示します
ENV JAVA_OPTS="-XX:+UseContainerSupport \
               -XX:MaxRAMPercentage=75.0 \
               -XX:+UseG1GC"

CMD java $JAVA_OPTS -jar app.jar
CODE_BLOCK_19__

5. プロダクションのモニタリング

必ず以下を追跡してください。

  • Heap usage (使用メモリ)

  • GC frequency (組み立て頻度)

  • GC pause time (休止時間)

  • Thread count (ストリーム数)

  • CPU usage

完成した構成の例

典型的なSpring Bootアプリケーションの場合:

#!/bin/bash
java -Xms2g -Xmx2g \
     -XX:MetaspaceSize=256m \
     -XX:MaxMetaspaceSize=256m \
     -XX:+UseG1GC \
     -XX:MaxGCPauseMillis=200 \
     -XX:+HeapDumpOnOutOfMemoryError \
     -XX:HeapDumpPath=/var/log/myapp/heapdump.hprof \
     -Xlog:gc*:file=/var/log/myapp/gc.log:time,uptime:filecount=10,filesize=100m \
     -Dcom.sun.management.jmxremote \
     -Dcom.sun.management.jmxremote.port=9010 \
     -Dcom.sun.management.jmxremote.authenticate=false \
     -Dcom.sun.management.jmxremote.ssl=false \
     -jar myapp.jar

追加ツール

  • GCEasy (gceasy.io) — GCログのオンライン分析

  • FastThread (fastthread.io)—スレッドダンプの分析

  • JProfiler — 商業プロファイラー

  • YourKit — もう一つの優れた商用プロファイラー

  • Arthas — ランタイム診断のための Alibaba のツール

結論

JVMの最適化は反復的なプロセスです。基本的な概念(ヒープ、GC、プロファイリング)を理解することから始め、適切な診断ツールを使用し、特定の負荷に合わせて徐々に最適化します。

覚えておいてください: 早すぎる最適化はすべての悪の根源です。まずは測定してから最適化しましょう!

役に立ちましたか?

参加する コディク — 開発者向けの教育プラットフォーム!

ここでは、Java、パフォーマンスの最適化、本番環境の準備に関する構造化されたコース、実践的なタスク、および関連資料をご覧いただけます。

また、当社には 急な テレグラムチャンネル フレンドリーなコミュニティ経験豊富な開発者が知識を共有し、問題を解決し、ベストプラクティスについて話し合う場所です。 参加してください!

🎯先延ばしをやめよう

記事は気に入った?
実践の時間だ!

Kodikでは読むだけでなく、すぐにコードを書く。理論 + 実践 = 本当のスキル。

即座に実践
🧠AIがコードを説明
🏆修了証

登録不要 • カード不要