WebSphere LibertyやOpen Libertyのコンテナ・イメージで使用されるJavaランタイムであるSemeru Runtimeは、コンテナ環境で稼働する場合、非コンテナ環境(物理OS上やVM仮想化OS上での稼働)とは異なるデフォルト値で稼働します。
WebSphere Application Server (tWAS)を、コンテナ環境のLibertyに移行する場合や、非コンテナ環境でのLibertyの設計/構築経験のあるエンジニアの方が、コンテナ環境(KubernetesやOpenShift上での稼働も含め)のLibertyを設計/構築される場合に、知っておくと有用と思いますので、Semeru Runtimeのコンテナ環境固有のデフォルト値について紹介します。
デフォルト最大ヒープサイズ
最大ヒープサイズは、Javaアプリケーションのチューニング・パラメーターとしてもっとも重要なパラメーターです。非コンテナ環境では、-XmxのJVMオプションで指定します。(tWAS環境では、管理コンソールで最大ヒープサイズの設定項目を指定しますが、内部的には-Xmxのオプションが指定されています。)
コンテナ環境で、memory limitが設定されている場合、 最大ヒープサイズのデフォルト値は、下記の表のようにコンテナのmemory limitを基準に設定されます。もちろんデフォルト値ですので、-Xmxが指定されている場合には、-Xmxの値が優先されます。
| コンテナのmemory limit (=<container memory size>) |
最大Javaヒープサイズ |
|---|---|
| 2GB以上 | <container memory size>の75% |
| 1GB以上、2GB以下 | <container memory size> - 512MB |
| 1GB以下 | <container memory size>の50% |
非コンテナ環境では、最大ヒープサイズのデフォルト値は、tWASの場合、メモリーサイズの25%(最大4GB)1で、Libertyの場合は、Javaのデフォルト値(Semeru Runtimeでは、メモリーサイズの25%(最大25GB)2)が、そのまま使用されますので、最大ヒープサイズ(-Xmx)を明示的に設定することがセオリーでしたが、コンテナ環境では、上記のデフォルト値、または、上記のデフォルトの変更と同時に導入された下記のコンテナ・メモリーサイズに対するパーセント値で最大/初期ヒープサイズを指定する方法もよい方法です。
| 設定 | 効果 |
|---|---|
| -XX:MaxRAMPercentage=N | 最大ヒープサイズを総メモリのパーセンテージとして設定 (Nは0~100までの値) |
| -XX:InitialRAMPercentage=N | 初期ヒープサイズを総メモリのパーセンテージとして設定 (Nは0~100までの値) |
特にコンテナ環境では、複数/大量のLibertyのコンテナを稼働させることも多いと思いますので、-Xmxの代わりに、-XX:MaxRAMPercentage=N(Nの値は個別に検討は必要ですが、デフォルトの75%は一つの目安になる)を設定することで、コンテナのmemory limitと、Javaの最大ヒープサイズを、個別に管理するのではなく、一貫して管理することができます。
また、最大ヒープサイズを、-XX:MaxRAMPercentage=Nで指定する場合には、初期(最小)ヒープサイズについても、デフォルト値を採用したり、-Xmsで指定するのではなく、-XX:InitialRAMPercentage=Nで指定するのがよいと思います。Semeru Runtimeの-Xmsのデフォルト値は、コンテナ環境であろうと、非コンテナ環境であろうと、8MBと非常に小さいですので、明示的に指定した方が良いです。
今回この記事を書くために、JVMオプションを眺めていて気付いたのですが、-XX:+UseGCStartupHintsというオプションがあり、デフォルトで有効です。このオプションは、Javaの起動時に、過去の起動時のヒープサイズをもとに、初期ヒープサイズを調整/最適化してくれます。ただ、コンテナ環境では、Javaの再起動ではなく、コンテナの再作成になると思いますので、この最適化が機能しません。ですので、コンテナ環境では、特に、-XX:InitialRAMPercentage=Nなどでの初期ヒープサイズの明示的な指定が重要です。
アイドル時のGCの実行
コンテナ環境と非コンテナ環境で異なるデフォルト値であることがマニュアルに明記されているJVMオプションとして、-XX:[+|-]IdleTuningGcOnIdleがあります。下記のように記載されています。
| Setting | Effect | Default | Default when running in a docker container |
|---|---|---|---|
-XX:+IdleTuningGcOnIdle |
Enable | ✓ | |
-XX:-IdleTuningGcOnIdle |
Disable | ✓ |
このJVMオプションをON(+)にすると、JVMがアイドル状態になったときに、ガベージコレクション(Global GC / Old領域のGC)を実行します。通常、GCは、New(nursery)領域、Old(tenure)領域のそれぞれについて、空き領域がなくなったことをトリガーにして、GCが行われますが、-XX:+IdleTuningGcOnIdleオプションがONの場合、JVMがアイドル状態のタイミングで、積極的にGCを行います。これにより、通常のGCの発生頻度、つまりユーザーの処理が行われている(アイドル状態ではない)タイミングでのGCの発生頻度が少なくなるという効果が期待できます。
このアイドル状態でのGCは、GCログ(verbose:gcのログ)に下記のようにsys-start reason="vm idle"と記録されます。
<sys-start reason="vm idle" id="6351" timestamp="2025-09-21T01:04:45.880" intervalms="195782111.697" />
このアイドル状態のGCの実行は、悪い機能とは思いませんが、もともと非コンテナ環境で稼働していたシステムを、コンテナ環境に移行し、夜間は処理がなかったり、ホット・スタンバイ機として稼働していたWASの場合、以前より、Global GCの発生頻度が増えたり、合計のGlobal GCの時間が長くなる場合があります。理由が分かれば、不要なチューニングや、設定変更を行う必要はありません。
また、-XX:+IdleTuningGcOnIdleオプションがアイドル状態のGC実行に関連するメインのJVMオプションですが、関連するJVMオプションを合わせて紹介しておきます。
| JVMオプション | 意味 | Default | Default when running in a docker container | 備考 |
|---|---|---|---|---|
-XX:IdleTuningMinIdleWaitTime |
アイドル状態と判定するまでの待ち時間。0が指定された場合は、アイドル状態の判定は行われない(つまり、-XX:-IdleTuningGcOnIdleが指定されているのと同じ)。 |
0 | 180(秒) |
-XX:+IdleTuningGcOnIdleがONの場合のみ有効 |
-XX:IdleTuningMinFreeHeapOnIdle |
パーセント単位(0-100の値)で指定。最低限ヒープの空き領域として確保するGC後の空き領域のパーセントを指定。残りは、OSに返却される。例えば、10を指定した場合、空き領域の最大90%がOSに返却される。 | 0 | 0 |
-XX:+IdleTuningGcOnIdleがONの場合のみ有効 |
-XX:[+|-]IdleTuningCompactOnIdle |
OpenJ9 バージョン 0.23.0以上では、効果なし。 もともとは、アイドル時のGC時にコンパクションを行うか否かを指定。 |
-XX:-IdleTuningCompactOnIdle |
-XX:+IdleTuningCompactOnIdle |
OpenJ9バージョン0.23.0は2020年10月リリース3のバージョンです。Java 17,21,25では、OpenJ9のバージョンが0.23.0未満のものはありません。 |
参考リンク
関連リンク
- OpenJ9 Doc "What's new in version 0.9.0" - "Specifying the maximum Java heap size as a percentage value"
- OpenJ9 Blog "Eclipse OpenJ9 in Containers"
- OpenJ9 Doc "Default settings for the Eclipse OpenJ9 VM"
- Eclipse Newsletter "Eclipse OpenJ9; not just any Java Virtual Machine"
- Eclipse OpenJ9 lightning talk (YouTube Video): Idle Tuning 2018-08-22
本記事で言及したJVMオプションのOpenJ9マニュアルのリンク