次の方法で共有


メモリ不足の問題によって引き起こされるアプリの再起動の問題

Note

Azure Spring Apps は、Azure Spring Cloud サービスの新しい名前です。 サービスの名前は新しくなりましたが、スクリーンショット、ビデオ、図などの資産の更新に取り組んでいる間、場所によってはしばらく古い名前が表示されます。

この記事の適用対象: ✔️ Basic または Standard ✔️ Enterprise

この記事では、Azure Spring Apps における Java アプリケーションのメモリ不足 (OOM) の問題について説明します。

メモリ不足の問題の種類

メモリ不足の問題には、コンテナー OOM と JVM OOM の 2 種類があります。

  • コンテナー OOM ("システム OOM" とも呼ばれます) は、アプリの使用可能なメモリが不足したときに発生します。コンテナー OOM の問題は、アプリの再起動イベントを引き起こし、それが Azure portal の [Resource Health] セクションで報告されます。 通常、コンテナー OOM はメモリ サイズの構成が正しくないことが原因で発生します。

  • JVM OOM は、使用メモリ量が JVM オプションで設定された最大サイズに達したときに発生します。 JVM OOM によってアプリが再起動されることはありません。 通常、JVM OOM はコードの不備が招く結果であり、アプリケーション ログから java.lang.OutOfMemoryError 例外を探すことで見つかります。 JVM OOM は、Java Flight Recorder などの Java プロファイリング ツールやアプリケーションに悪影響を及ぼします。

この記事では、コンテナー OOM の問題を修正する方法について説明します。 JVM OOM の問題を解決するには、ヒープ ダンプ、スレッド ダンプ、Java フライト レコーダーなどのツールを確認します。 詳細については、「Azure Spring Apps でヒープ ダンプとスレッド ダンプを手動でキャプチャして Java Flight Recorder を使用する」を参照してください。

OOM によるアプリの再起動の問題を修正する

以降のセクションでは、コンテナー OOM の問題の診断と修正に使用できるツール、メトリック、JVM オプションについて説明します。

[Resource Health] ページでアラートを確認する

Azure portal の [Resource Health] ページには、コンテナー OOM によるアプリの再起動イベントが次のスクリーンショットのように表示されます。

Screenshot of Azure portal showing Azure Spring Apps Resource Health page with OOM message highlighted.

メモリ サイズを構成する

メモリ使用量は、"アプリのメモリ使用量" のメトリックである jvm.memory.usedjvm.memory.committed で観察できます。 詳細については、「メモリの問題をトラブルシューティングするためのツール」の「メトリック」セクションを参照してください。 JVM オプションで最大メモリ サイズを構成して、メモリが制限を超えないようにする必要があります。

Java メモリ モデル内のすべての領域の最大メモリ サイズの合計が、実際に使用可能なアプリ メモリよりも小さくなるようにする必要があります。 最大メモリ サイズを設定するには、「Java のメモリ管理」の「メモリ使用量レイアウト」セクションで説明されている一般的なメモリ レイアウトを参照してください。

最大メモリ サイズを設定するときは、バランスを見出すようにしてください。 最大メモリ サイズを大きくしすぎると、コンテナー OOM のリスクが生じます。 最大メモリ サイズを小さくしすぎると、JVM OOM のリスクが生じ、アプリのガベージ コレクションが発生してアプリの速度が低下します。

ヒープ メモリを制御する

最大ヒープ サイズは、JVM のオプションである -Xms-Xmx-XX:InitialRAMPercentage-XX:MaxRAMPercentage を使用して設定できます。

メトリックの jvm.memory.used の値が大きすぎるときは、最大ヒープ サイズの設定を調整する必要があります。 詳細については、「メモリの問題をトラブルシューティングするためのツール」の「jvm.memory.used/committed/max」セクションを参照してください。

ダイレクト メモリを制御する

次の理由により、JVM オプションの -XX:MaxDirectMemorySize を設定することが重要となります。

  • nio や gzip などのフレームワークによっていつダイレクト メモリが使用されるかはわからない場合がある。
  • ダイレクト メモリのガベージ コレクションは完全なガベージ コレクション時にしか行われず、完全なガベージ コレクションはヒープがいっぱいになりそうなときにしか発生しない。

通常、アプリのメモリのサイズから、ヒープ メモリとヒープ以外のメモリを差し引いた値を超えないように MaxDirectMemorySize の値を設定してください。

メタスペースを制御する

メタスペースの最大サイズを設定するには、JVM オプション -XX:MaxMetaspaceSize を設定します。 完全なガベージ コレクションをトリガーするしきい値は、-XX:MetaspaceSize オプションで設定します。

通常、メタスペースのメモリは安定しています。

関連項目