extend-troubleshooting-oom-java
注釈:本資料はAI技術を用いて翻訳されています。
概要
Java Extend アプリはガベージコレクターを使用してシステムメモリを自動的に管理します。ただし、次の理由によりメモリの問題が発生する可能性があります。
- 非効率的なデータ構造
- 必要以上に長い間、大きなオブジェクトへの参照を保持する
- メモリリーク
- 一般的な高メモリ使用量
ベストプラクティス
- ニーズに適したデータ構造を選択してください。例えば、ソートが不要な場合は TreeMap ではなく HashMap を使用します。ArrayList の場合、予想されるサイズがわかっている場合は、作成時にそれを指定して、コストがかかる可能性のあるリサイズ操作を最小限に抑えます。
- String は不変であるため、String の連結は避けてください。代わりに
StringBuilderを使用してください。 - 特に大きなオブジェクトは、不要になったらすぐにコレクションから削除してください。
- CPU とメモリのプロファイリングを開発サイクルに組み込んで、メモリリークとパフォーマンスのボトルネックを早期に発見してください。
- ガベージコレクションとヒープサイズを最適化します。パフォーマンス目標に基づいてガベージコレクションとヒープサイズを調整します。初期ヒープと最大ヒープ(
-Xms/Xmx)のヒープサイズを調整することで、実行時のリサイズを防ぎます。過度なガベージコレクションアクティビティを減らすために、ヒープサイズを十分に大きく設定してください。 - オブジェクトの作成を最小限に抑えるか、可能な限りオブジェクトを再利用してください。頻繁に作成および破棄される高コストなオブジェクトにはプールの使用を検討してください。
- 遅延初期化を活用して、必要になるまで作成を遅らせることで、初期メモリ消費を削減し、起動時間を改善します。
- 他のソースから取得するデータの量を制限してください。
- ネイティブコードは Java 仮想マシン(JVM)のメモリ管理をバイパスする手動メモリ管理を必要とすることが多いため、使用を避けてください。ネイティブコードの不適切な使用は、メモリリーク、クラッシュ、予期しない動作につながる可能性があります。ネイティブコードを使用する場合は、ネイティブリソースが適切に解放されるように慎重に管理してください。
推奨ツール
CPU とメモリの使用量を管理するために、次のツールの使用をお勧めします。
IntelliJ Profiler
IntelliJ Profiler は、CPU とメモリの使用量を分析してコードを最適化するように設計された、さまざまなプロファイリング機能を備えたパフォーマンス分析ツールです。Intellij を Extend アプリと統合するには、次の手順に従います。
- IntelliJ で Profile with IntelliJ Profiler を選択して Extend アプリケーションを起動します。
- Run > Profile [your application name] with IntelliJ Profiler でアプリケーションを実行します。
- プロファイリングが完了したら、Stop Recording and Show Results をクリックします。CPU sampling - Flame Graph の結果が表示されます。

- 結果ビューを CPU samples と Memory samples の間で切り替えます。次の画像は、Memory samples ビューの結果を示しています。

詳細については、IntelliJ Profiler のドキュメントの CPU プロファイリングとメモリリークの検出を参照してください。
IntelliJ Profiler と VisualVM
IntelliJ Profiler を VisualVM と併用して、Java Management Extensions(JMX)からのライブ結果と、保存された Java Flight Recorder(JFR)ファイルから結果を取得できます。次の手順に従います。
- VisualVM で、Local の下で実行中のアプリケーションを選択し、アプリケーションをダブルクリックして接続します。ライブ接続すると、VisualVM は CPU とメモリ使用量のライブモニタリング結果を表示します。
- その後、次の操作を実行できます。
- Sampler タブに移動して、CPU とメモリのサンプリングを開始します。
- CPU サンプル

- メモリサンプル

- CPU サンプル
- Profiler タブに移動して、ソースメソッドまでのオブジェクトのメモリ使用量を確認します。

詳細については、VisualVM のドキュメントを参照してください。
Docker コンテナ
JVM のビルドとバージョンによっては、一部の機能がサポートされていない場合があります(例:ibm-semeru-runtimes:open-17-jre ビルドではヒープダンプが無効になっている場合があります)。Docker のサポートされている機能の詳細については、Docker コンテナのドキュメントを参照してください。
Java Extend アプリで Docker コンテナを使用するには、次の手順に従います。
- リモートモニタリング用に JMX 接続を開きます。
- JVM 引数を介して JMX 接続を有効にします。イベントハンドラーアプリテンプレートの場合、
docker-compose.yamlのJAVA_OPTS環境変数を介して JMX 接続を有効にできます。- JAVA_OPTS=-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.rmi.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 - JMX ポートを公開してください。例えば、
docker-compose.yamlの Ports の下に- "9010:9010"を追加します。
- JVM 引数を介して JMX 接続を有効にします。イベントハンドラーアプリテンプレートの場合、
- docker compose を使用してアプリケーションを起動します。
- VisualVM を開き、新しい JMX 接続を追加して、アドレス(例:ステップ 1 で設定した公開 JMX ポートの
localhost:9010)を入力します。
Java Flight Recorder(JFR)と JDK Mission Control(JMC)
Java Flight Recorder(JFR)と JDK Mission Control(JMC)は、アプリケーションの起動からのイベントログを含む診断データの収集に役立ちます。これらのツールの詳細については、Oracle の JFR ランタイムガイドを参照してください。
商用ライセンスの使用については、JDK ディストリビューションを再確認してください。
Java Extend アプリで JFR と JDK を使用するには、次の手順に従います。
- リモートモニタリング用に JMX 接続を開きます。
- JVM 引数を介して JMX 接続を有効にします。イベントハンドラーアプリテンプレートの場合、
docker-compose.yamlのJAVA_OPTS環境変数を介して JMX 接続を有効にできます。- JAVA_OPTS=-Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=9010 -Dcom.sun.management.jmxremote.rmi.port=9010 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 - Java extend アプリケーションの起動時に JFR で 60 秒の記録を自動的にキャプチャするには、次の環境変数を設定します。
- JAVA_OPTS=-XX:StartFlightRecording=filename=/tmp/startupProfiling.jfr,duration=60s,settings=profile - JMX ポートを公開してください。例えば、
docker-compose.yamlの Ports の下に- "9010:9010"を追加します。
- JVM 引数を介して JMX 接続を有効にします。イベントハンドラーアプリテンプレートの場合、
- JMC を開き、生成された JFR ファイルを見つけます。JFR ファイルがローカルにない場合は、Docker コンテナからコピーできます。
- 分析を開始します。オプションで、オンデマンドでフライト記録を開始および停止するように JFR に指示することもできます。

-
メモリのサンプル結果

-
メソッドプロファイリングのサンプル結果

-
Event Types Tree の Thread CPU Load のサンプル結果

参考資料
Oracle のトラブルシューティングガイドから次の記事を読むことをお勧めします。
- 一般的なトラブルシューティング
- JVM 問題のデバッグ(システムクラッシュまたはハングと例外のトラブルシューティング)