CMS: 聞いてください、これが本番環境で JVM パラメータを構成する方法です

CMS: 聞いてください、これが本番環境で JVM パラメータを構成する方法です

[[413156]]

JDK16 GA がリリースされてからかなり経ちますが、ほとんどの本番環境では依然として JDK8 が実行されていることは確かです。ここで一言言わなければなりません: JDK8 yyds。 JDK8 が稼働しているため、本番環境のガベージ コレクターは基本的に次の 3 つになります。

  • PS (JDK8 デフォルト)
  • コンテンツ管理システム
  • G1

デフォルトのガベージコレクター

この記事では、CMS をガベージ コレクターとして使用する、より合理的な JVM パラメータを構成する方法にのみ焦点を当てます。まず最初に言っておきたいのは、JDK8 が CMS を使用する場合、使用するデフォルトのガベージ コレクターは ParallelGC であるため、明示的に宣言する必要があるということです。デフォルトで使用されるガベージ コレクターを確認するにはどうすればよいでしょうか?とても簡単です。次のコードを実行するだけです。

  1. パッケージ com.afei.test.main;
  2.  
  3. java.util.ArrayList をインポートします。
  4. java.util.List をインポートします。
  5.  
  6. /**
  7. * @author 公開アカウント: A Fei's Blog
  8. */
  9. パブリッククラスMain {
  10.  
  11. プライベート静的最終int _1M = 1024*1024;
  12.  
  13. 公共 静的void main(String[] args) {
  14.  
  15. リスト<byte[]> byteList = 新しいArrayList<>();
  16. ( int i=0; i<整数.MAX_VALUE; i++) {
  17. byte[]テスト = 新しいbyte[_1M];
  18. byteList.add (テスト);
  19. }
  20. }
  21.  
  22. }

次に、JVM パラメータを構成します。

  1. -verbose:gc -XX:+PrintGCDetails

数秒間実行した後、JVM プロセスを強制的に停止し、コンソールに次のログが表示されます。これは、JDK8 で使用されるデフォルトのガベージ コレクターが ParallelGC であることを証明しています。

  1. [フルGC (割り当て失敗) [PSYoungGen: 342021K->342021K(348672K)] [ParOldGen: 1397423K->1397406K(1398272K)] 1739445K->1739427K(1746944K)、[メタスペース: 3357K->3357K(1056768K)​​]、0.1902415 秒] [時間:ユーザー=0.26、システム =0.01、=0.19 秒]

または、次の情報から、デフォルトのガベージ コレクターが ParallelGC であることを知ることができます。

CMS の使用

次に、著者は、CMS ガベージ コレクターをさまざまな観点から使用するための、より適切な JVM パラメータを構成する方法を紹介します。

ディスプレイ宣言CMS

ガベージ コレクターを CMS+parNew として明示的に宣言するのは非常に簡単です。次の 2 つの JVM パラメータを追加するだけです。

  1. -XX:+ConcMarkSweepGC を使用 -XX:+ParNewGC を使用

このとき、上記のコードを再度実行すると、以下の情報が得られます。下の図からわかるように、この時点で若い世代は ParNew を使用し、古い世代は CMS (concurrent mark-sweep) を使用します。

CMS を明示的に宣言することは、CMS を使用するための最初のステップにすぎません。まだ実行する必要がある最適化が多数あり、構成を待っている JVM パラメータも多数あります。

ヒープサイズ

次に、最も重要なことは、若い世代と古い世代の大きさを宣言することです。 CMS+ParNewを使用しているため。 CMS + ParNew の組み合わせで発生する FGC では MSC アルゴリズムとシングルスレッド リカバリが使用されるため、ヒープ サイズは 8G を超えず、できれば 6G 以内にすることをお勧めします。ヒープメモリが大きい場合、FGC 中の STW 時間は非常に長くなります。ここで著者は 4G を例に挙げています。この時点で、いくつかの JVM パラメータを追加すると、次の構成が得られます。ここで私が設定した若い世代は約 1.5G、古い世代は約 2.5G です。これは比較的妥当な比率です。 JVM パラメータがこのように一致していても GC 状況がまだあまり良くない場合は、ビジネス特性に基づいて特別なチューニングを実行する必要がある可能性があります。

  1. -Xmx4g -Xms4g -Xmn1512m

スレッドスタック

JDK8 のデフォルトのスレッド スタック サイズは 1M ですが、これは少し大きいです。私の経験では、ほとんどのマイクロサービス プロジェクトは 512k または 256k に調整できます (私のプロジェクトは 256k ですが、問題なく動作します)。

  1. -Xss256k

古いリサイクル敷居

CMS が設定されているので、次の 2 つのパラメータを追加する必要があります。なぜこれら 2 つの JVM パラメータを追加する必要があるのでしょうか?これは、CMS の収集条件が非常に複雑であるためです。 CMSInitiatingOccupancyFraction と UseCMSInitiatingOccupancyOnly を使用して、古い世代が 75% に達した場合にのみコレクションを制限しないと (このしきい値は特定の状況に応じて適切に調整できます)、オンラインで CMS GC が発生した場合に原因を突き止めるのが難しくなります。

  1. -XX:CMSInitiatingOccupancyFraction=75 -XX:+CMSInitiatingOccupancyOnly を使用する

CMS GC トリガー条件に関連する推奨記事 - [CMS GC トリガー条件の JVM ソースコード解釈]: https://mp.weixin.qq.com/s/Mu-Xz4CLgdxJhcMJ7aKAHg

メタデータスペース

マイクロサービス アーキテクチャの場合、ほとんどのアプリケーションでは 128 MB のメタデータで十分です。ただし、JDK8 のメタデータ領域は指定されたサイズに初期化されません。代わりに、メタデータ スペースは必要に応じて拡張されます。したがって、256M を設定できます。これら 2 つのパラメータが設定されていない場合、メタデータ スペースのデフォルトの初期化サイズは 20 MB をわずかに超えるだけであり、アプリケーションの起動時にメタスペースが拡張されると FGC が発生します。

  1. -XX:最大メタスペースサイズ=256m -XX:メタスペースサイズ=256M

ダンプパス

以下の 2 つのパラメータを設定します (HeapDumpPath パラメータで指定するパスは事前に作成しておく必要があり、JVM はダンプ ファイルを生成するときにこのディレクトリを作成できないことに注意してください)。 JVM メモリによって JVM プロセスが終了すると、次のディレクトリにダンプ ファイルが自動的に生成されます。

  1. -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/log/jvmdump/

GCログ

これは必須です。そうしないと、オンライン環境での GC の問題のトラブルシューティングが難しくなります。また、loggc が配置されているディレクトリ (/data/log/gclog/) はダンプ パスと同じであり、事前に作成する必要があります。 JVM はこのディレクトリを自動的に作成できません:

  1. -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/data/log/gclog/gc.log

圧縮

CMS GC は、圧縮アルゴリズムではなく、マークアンドスイープ アルゴリズムを使用する同時実行ガベージ コレクターであることは誰もが知っています。つまり、時間が経つにつれて断片化が増加し、最終的に JVM がメモリ圧縮アクションをトリガーすることになります。では、メモリはいつデフラグすべきでしょうか?それは次の 2 つのパラメータと大きく関係しています。最初のパラメータはこの機能を有効にするためのもので、2 番目のパラメータはメモリの圧縮 (コンパクション) の前に非圧縮メモリの FGC が何回発生する必要があるかを示します。 CMS GC は FGC ではありません。 CMS GC が処理できない場合 (同時モード障害など)、完全な STW だが圧縮されていない FGC (NoCompactFGC という名前であると想定) がトリガーされるか、完全な STW と圧縮された FGC (CompactFGC という名前であると想定) がトリガーされます。したがって、このパラメータは、CompactFGC がトリガーされる前に連続して何回 NoCompactFGC がトリガーされるかを意味します。途中で CMS GC が発生した場合は、NoCompactFGC の発生回数を再計算する必要があります。

  1. -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0

CMS リサイクル条件に関する推奨記事 - [JVM ソースコード解釈: CMS はいつフル GC を実行するか]: https://mp.weixin.qq.com/s/zn3-9e7ZZ7skLo1XDL0xww

ここで指定されている設定は実際にはデフォルト値であり、CMS GC が処理に失敗するたびに CompactFGC がトリガーされます。これら 2 つのパラメータは理解するのが困難です。このため、いくつか例を挙げてみたいと思います。 GC モードには CMS GC、NoCompactFGC、CompactFGC の 3 つがあると仮定します (以下を参照)。

  1. if(should_compact){
  2. // マークスイープコンパクト
  3. do_compaction_work(すべてのソフト参照をクリア)
  4. }それ以外{
  5. // マークスイープ
  6. do_mark_sweep_work(すべてのソフト参照をクリアし、最初の状態を維持し、最初からやり直す必要があります);
  7. }

NoCompactFGC は、メモリを圧縮せず、Mark-Sweep アルゴリズムを使用する FGC です。 CompactFGC は、メモリを圧縮し、Mark Sweep Compact アルゴリズムを使用する FGC です。 -XX:CMSFullGCsBeforeCompaction=3 を設定すると、次のようになります。

  1. 1. CMS GC、NoCompactFGC、NoCompactFGC、NoCompactFGC、CompactFGC(この時点でFGCが発生するとメモリが圧縮されます)
  2. 2. CMS GC、NoCompactFGC、NoCompactFGC、CMS GC、NoCompactFGC (この時点で FGC が発生した場合、これ以前に 3 回連続して NoCompactFGC が発生していないため、メモリは圧縮されません)
  3. 3. CMS GC、CMS GC、CMS GC、NoCompactFGC (以前に CMS GC が連続して発生した場合、次にトリガーされる FGC はメモリを圧縮しません)

もう1つ

最後に、以下に示すように、CMS と組み合わせると非常に便利な JVM パラメータをお勧めします。このパラメータの正式な説明は次のとおりです: System.gc() 要求は同時コレクションを呼び出し、このような同時 gc サイクル中にクラスもアンロードします (UseConcMarkSweepGC の場合にのみ有効)。この文は次のように要約できます: 1. CMS を使用する場合にのみ機能します。 2. System.gc() が呼び出されると、リサイクルに CMS 並列ガベージ コレクターが使用されます (たとえば、オフヒープ メモリ操作に DirectByteBuffer が頻繁に使用される場合、オフヒープ メモリをリサイクルするには FGC が必要です。このパラメーターを使用すると、元々 FGC を必要としていたものを CMS GC で処理できるようになります)。 3. 並列ガベージ コレクターを呼び出すだけでなく、クラスをアンロードすることもできます。

  1. -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses

最後に、完全な JVM パラメータ構成は次のようになります (このパラメータは、私が以前担当していたマイクロサービス プロジェクトで数年間実行されており、単一マシンの同時実行数は 1000 を超え、CMS GC は 8 日に 1 回程度です)。

  1. -Xms4g -Xmx4g -Xmn1512m -server -Xss256k -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=256m -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:/data/log/gclog/gc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/data/log/jvmdump/ -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:+TieredCompilation -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses

最後に、JVM パラメータを検証するための優れた Web サイト https://opts.console.heapdump.cn/ を紹介します。ここでは、「パラメータ チェック」を使用できます。しかし、本を盲目的に信じるよりも読まない方が良いということに留意すべきです。当ウェブサイトの検証結果は参考値です。これらが本番環境と完全に一致しているかどうかは状況によって異なります。結局のところ、JVM のチューニングは簡単な作業ではありません。

この記事はWeChatの公開アカウント「A Fei's Blog」から転載したものです。下のQRコードからフォローできます。この記事を転載する場合は、A Fei のブログ公開アカウントにご連絡ください。

<<:  サービス効率を向上させるにはどうすればよいでしょうか? Ruiyun Service Cloudはテクノロジーを活用して産業用ロボット業界を強化します

>>:  ハードウェアの観点から見たエッジコンピューティングとは何ですか?

推薦する

Fanstong | 戦略戦争ゲームの実践的な共有開始

「Invasion」はtap4funが開発・運営する3D戦略戦争ゲームです。2015年9月2日より全...

ウェブサイトがオンラインになったときに、慌てて追加しないでください。サイトの最適化を整理することが最優先事項です。

多くのウェブサイト所有者がウェブサイトをオンラインにした後、最も望んでいることの 1 つは、ウェブサ...

Baidu リアルタイム ホットスポットは新しいプロモーション方法でしょうか?

はじめに: Baidu が「トップ 10 リアルタイム ホットスポット」(Baidu ホームページの...

budgetnode-VPS プロモーション/ダブルメモリ/カスタム ISO/4 データセンターの許可

budgetnode は、格安 VPS の特別プロモーションを提供しています。オランダ、アッシュバー...

millenial: 香港 NAT VPS、1Gbps 帯域幅、初月 1 ドル、512M メモリ/1 コア/5gSSD/1T トラフィック

millenial.host は hosthongkong のサブブランドのようです。現在、香港 N...

4月のアプリ購入動向に関する考察

4月、趣頭条は6月30日に自社メディア作成プラットフォームのサービスとメンテナンスを停止すると発表し...

onetechcloud: 新年 20% オフ、(ネイティブ IP) US cn2 gia vps、US cn2 gia 高防御 vps、香港と日本の無制限トラフィック CN2 VPS

OneTechCloudは今年最初のプロモーションを開始し、米国CN2 GIA VPS(ネイティブI...

クラウドネイティブ時代を1万語で解説、K8sコンテナプラットフォームのLB(Nginx)負荷分散システムを0から1に構築する方法

クラウドネイティブ時代において、Kubernetes をベースとしたコンテナ オーケストレーション ...

12306ウェブサイトはネットワーク機器の購入に5億から2億以上を投資した

■ ホットスポットインターネットによると、12306のウェブサイトは5億ドル以上を投資したという。内...

ウェブマスターネットワークレポート:Renren Videoが再びダウン、Fanke Chennianはトラフィックウォッシングの首謀者に激怒

1. Renren Videoが再びダウン、類似のウェブサイトは通常通りアクセス可能A5 Webma...

生放送週間レビュー日記5日目:「クラウド」ってどれくらい面白いの?アボリジニは言う

5月13日、Amazon Web Servicesと51CTOは共同でライブ放送週間シリーズ「Thi...

2019年のWeChatマーケティング活動10種類!

はじめに:今日は、WeChat で最も一般的な 10 種類のアクティビティについて詳しく紹介します。...

ソフト記事でビジネス情報をよりうまく隠す方法

彼は剣士である。2002年に彼が書いた「商人の涙」という記事が全国紙「読者」に転載されたが、これは事...