AWS Elastic Container Service(ECS) Fargate でいくつかの Java サービス (Corretto JDK21) を実行しています。各サービスには独自のコンテナがあり、各プロセスに支払っている可能なリソースをすべて使用したいと考えています。ただし、この手順は EC2 や他のクラウドにも適用できます。
サービスはバッチ ジョブを実行しており、遅延は重要ではありません。並列 GC (-XX: UseParallelGC) を使用します。私たちのタスクでも G1 の方が良いかもしれませんが、それは別の研究と投稿のトピックです。
利用可能なすべてのメモリを使用するには、MaxHeapSize をコンテナのメモリ サイズより少し小さくします。しかし、しばらくしてから、2 つの問題に気づきました。コンテナーがメモリ使用量が多すぎるために強制終了される場合と、OutOfMemoryError 例外を受け取る場合があります。 1 つ目の問題を修正するために、コンテナーのメモリ サイズと MaxHeapSize の間のギャップを増やし、2 つ目の問題については、簡単な修正としてコンテナーのメモリを増やし、ヒープ ダンプの確認を開始しました。
ヒープ ダンプには興味深い詳細が示されており、実際のヒープ サイズは MaxHeapSize より小さく、若い世代のヒープは古い世代に比べて小さかったです。
インターネットで検索しても、今回のケースに合わせて JVM パラメーターを調整する方法に関する適切なガイドは見つかりませんでした。ヒープとパラメーターの説明に関する大まかな詳細しか見つかりませんでした。私が行った手順を説明するためにこの投稿を書くことにしました。
最初のステップは次のとおりです:
若い世代:古い世代のデフォルトの比率は 1:2 で、若い世代の一部のみが GC の実行に同時に使用されます。そして、起動後、JVM は予想どおりにすべてのメモリを割り当てましたが、しばらくすると、Young Generation ヒープ サイズが数メガバイト近くまで減少し始めました。そのため、しばらくすると、使用可能なメモリのわずか 2/3 が使用されました。
いくつか調べた結果、アダプティブ ポリシーを無効にするパラメーター (-XX:-UseAdaptiveSizePolicy) を見つけました。これが役に立ち、ヒープの減少が止まり、ガベージ コレクションの間隔が 1 桁以上増加しました。 GC にかかる時間も同様に増加しましたが、それほど大きくはありませんでした。
次のステップは、コンテナーのメモリ サイズ間の最適なギャップを見つけることでした。デフォルトでは、InitialRAMPercentage=100 であっても、JDK はメモリを割り当てるだけで使用しないため、マップされません。 Linux では、物理メモリよりも多くの仮想メモリを割り当てることができます。そして、後で実際にメモリがマップされるとき (JDK がメモリに書き込むとき)、コンテナは失敗します。 -XX: AlwaysPreTouch はこの動作を変更します。残念ながら、一部のメモリはまだマップされていませんが、OOM の終了ははるかに高速に行われます。何度か試した結果、次の式「コンテナーのメモリー サイズ - 8GB 以上のメモリーを備えたコンテナーの場合は 1024MB」で終了しました。たとえば、8192 コンテナー メモリ サイズの場合、-XX:MaxHeapSize=7168m.
を使用します。さらなる最適化のために、-XX:NewRatio を変更して Young Generation サイズを減らし、GC 時間を短縮することを検討しています。ただし、それはアプリケーション内のオブジェクトの存続期間によって異なります。
前に述べたように、パラメーター (私が見つけた最良のものは vm-options-explorer) とチューニング手順の詳細な説明を記載した適切なガイドが見つかりませんでした。あなたの知識や結果を共有していただければ幸いです。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3