Java アプリケーションをコンテナー化する

この記事では、Java アプリケーションをコンテナー化するための推奨される方法と設定の概要について説明します。

Java アプリケーションをコンテナー化する場合は、コンテナーが使用できる CPU 時間を慎重に検討してください。 次に、メモリの合計量と Java 仮想マシン (JVM) のヒープ サイズの両方に関して使用可能なメモリの量を検討します。 コンテナー化された環境では、アプリケーションはすべてのプロセッサにアクセスできるため、複数のスレッドを並行して実行できる場合があります。 ただし、コンテナーには CPU へのアクセスを調整できる CPU クォータが適用されているのが一般的です。

JVM には、CPU クォータに基づいて "使用可能なプロセッサ" の数を決定するヒューリスティックがあります。これは、Java アプリケーションのパフォーマンスに大きく影響する可能性があります。 コンテナー自体に割り当てられたメモリと JVM のヒープ領域のサイズは、プロセッサと同じくらい重要です。 これらの要因によって、ガベージ コレクター (GC) の動作とシステムの全体的なパフォーマンスが決まります。

新しいアプリケーションをコンテナー化する

新しいアプリケーション用に Java ワークロードをコンテナー化する場合は、メモリについて考えるときに、次の 2 つのことを考慮する必要があります。

  • コンテナー自体に割り当てられたメモリ。
  • Java プロセスで使用できるメモリの量。

JVM の既定の人間工学を理解する

アプリケーションには、始点と設定が必要です。 JVM には、システム内の使用可能なプロセッサの数とメモリの量に基づいて事前に定義された値を持つ既定の人間工学があります。 次の表に示す既定値は、JVM が特定のスタートアップ フラグまたはパラメーターなしで起動されるときに使用されます。

次の表は、使用可能なリソースに使用される既定の GC を示しています。

利用可能なリソース 既定の GC
任意の数のプロセッサ
最大 1791 MB のメモリ
SerialGC
2 つ以上のプロセッサ
1792 MB 以上のメモリ
G1GC

次の表は、JVM が実行されている環境で使用可能なメモリの量に応じて、既定の最大ヒープ サイズを示しています。

使用可能なメモリ 既定の最大ヒープ サイズ
最大 256 MB 使用可能なメモリの 50%
256 MB から 512 MB 最大 127 MB
512 MB を超える 使用可能なメモリの 25%

既定の 初期ヒープ サイズ は、使用可能なメモリの 1/64 です。

これらの値は、OpenJDK 11 以降、およびほとんどのディストリビューション (Microsoft Build of OpenJDK、Azul Zulu、Eclipse Temurin、Oracle OpenJDK など) で有効です。

コンテナー のメモリを決定する

アプリケーションのニーズとその固有の使用パターンに応じて、作業負荷に最適なコンテナー メモリ量を選択します。 たとえば、アプリケーションで大きなオブジェクト グラフを作成する場合、多くの小さなオブジェクト グラフを持つアプリケーションに必要なメモリよりも多くのメモリが必要になる可能性があります。

ヒント

割り当てるメモリの量がわからない場合、4 GB から始めることをお勧めします。

JVM ヒープ メモリを決定する

JVM ヒープ メモリを割り当てる場合は、JVM は JVM ヒープに使用されるメモリよりも多くのメモリを必要とすることに注意してください。 最大 JVM ヒープ メモリを設定する場合、コンテナー メモリ不足 (OOM) エラーが発生し、コンテナーがクラッシュするため、コンテナー メモリの量と同じにしないでください。

ヒント

JVM ヒープにコンテナー メモリの 75% を割り当てます。

OpenJDK 11 以降では、JVM ヒープ サイズを次の方法で設定できます。

説明 フラグ
固定値 -Xmx -Xmx4g
動的な値 -XX:MaxRAMPercentage -XX:MaxRAMPercentage=75

最小/初期ヒープ サイズ

環境が JVM インスタンス (コンテナー内など) に一定の量のメモリを予約することが保証されている場合は、最小ヒープ サイズ (初期ヒープ サイズ) を最大ヒープ サイズと同じサイズに設定する必要があります。 この設定は、メモリを OS に解放するタスクを実行しないことを JVM に示します。

最小ヒープ サイズを設定するには、絶対量または-XX:InitialRAMPercentage割合の量に を使用-Xmsします。

重要

フラグ -XX:MinRAMPercentageは、名前が示しているにもかかわらず、システムで使用可能な RAM が最大 256 MB のシステムの既定の 最大 RAM 割合を設定するために使用されます。

OpenJDK 17 の既定のヒープ サイズを示すグラフ。

使用する GC を決定する

既に、開始する JVM ヒープ メモリの量は決定しました。 次の手順では、GC を選択します。 多くの場合、使用している JVM ヒープ の最大メモリ量は、GC を選択する際の要因です。 次の表で、各 GC の特徴について説明します。

考慮すべき要素 SerialGC ParallelGC G1GC ZGC ShenandoahGC
コア数 1 2 2 2 2
マルチスレッド いいえ はい はい はい はい
Java ヒープ サイズ <4 GB <4 GB >4 GB >4 GB >4 GB
一時停止 はい はい はい はい (<1 ms) はい (<10 ms)
オーバーヘッド 最小限 最小限
テイル レイテンシーの影響
JDK バージョン All All JDK 8 以降 JDK 17 以降 JDK 11 以降
最適な用途 単一コアの小さいヒープ 任意のヒープ サイズを持つマルチコアの小さいヒープまたはバッチ ワークロード 中から大のヒープ (要求 - 応答/DB の相互作用) での応答性 中から大のヒープ (要求 - 応答/DB の相互作用) での応答性 中から大のヒープ (要求 - 応答/DB の相互作用) での応答性

ヒント

ほとんどの汎用マイクロサービス アプリケーションでは、パラレル GC から始めます。

必要な CPU コア数を決定する

SerialGC 以外の GC の場合は、2 つ以上の vCPU コア (または Kubernetes で少なくとも 2000mcpu_limit することをお勧めします。 コンテナー化された環境では、1 つ未満の vCPU コアを選択することはお勧めしません。

ヒント

開始するコアの数がわからない場合は、2 つの vCPU コアを選択することをお勧めします。

始点を選択する

Kubernetes、OpenShift、Azure Spring Apps、Azure Container Apps、Azure App Service などのコンテナーのオーケストレーション環境では、2 つのレプリカまたはインスタンスから開始することをお勧めします。 次の表は、新しい Java アプリケーションのコンテナー化に推奨される始点をまとめたものです。

vCPU コア コンテナー メモリ JVM ヒープ サイズ [GC] レプリカ
2 4 GB 75% ParallelGC 2

使用する JVM パラメーターは次のとおりです。-XX:+UseParallelGC -XX:MaxRAMPercentage=75

既存の (オンプレミス) アプリケーションをコンテナー化する

アプリケーションが既にオンプレミスまたはクラウド内の VM で実行されている場合は、まず次の手順から始めることをお勧めします。

  • アプリケーションが現在アクセスできるメモリの量と同じです。
  • アプリケーションが現在使用できる CPU (vCPU コア) の数と同じです。
  • 現在使用しているのと同じ JVM パラメーター。

vCPU コアやコンテナー メモリの組み合わせが使用できない場合は、最も近いものを選択して、vCPU コアとコンテナー メモリを切り上げてください。

次のステップ

Java アプリケーションのコンテナー化に関する一般的な推奨事項を理解したら、次の記事に進み、コンテナー化ベースラインを確立します。