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 が実行されている環境で使用可能なメモリの量に応じたデフォルトの最大ヒープ サイズを示しています。

使用可能なメモリ 既定の最大ヒープ サイズ
最大256MB 使用可能なメモリの 50%
256 MB から 512 MB ~127MB
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 に示します。

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

重要

フラグ -XX:MinRAMPercentageは、その名前が示すとおり、システムで利用可能な最大 256 MB の RAM を持つシステムのデフォルトの 最大 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
Pause はい イエス はい はい (<1 ms) はい (<10 ms)
間接費 最小 最小
テイル レイテンシーの影響
JDK バージョン すべて すべて JDK 8 以降 JDK 17 以降 JDK 11 以降
最適な用途 単一コアの小さいヒープ 任意のヒープ サイズを持つマルチコアの小さいヒープまたはバッチ ワークロード 中から大のヒープ (要求 - 応答/DB の相互作用) での応答性 中から大のヒープ (要求 - 応答/DB の相互作用) での応答性 中から大のヒープ (要求 - 応答/DB の相互作用) での応答性

ヒント

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

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

SerialGC 以外の GC の場合は、2 つ以上の vCPU コア、または Kubernetes 上で少なくとも 2000m cpu_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 アプリケーションのコンテナー化に関する一般的な推奨事項を理解したら、次の記事に進み、コンテナー化ベースラインを確立します。