JVM の新世代と旧世代のデフォルトの比率は本当に 1:2 ですか?

JVM の新世代と旧世代のデフォルトの比率は本当に 1:2 ですか?

[[392981]]

画像はPexelsより

[51CTO.com オリジナル記事]業界の一般的な認識は下図の通りです。それは正しいですか?

まず結論: プロセスを開始するときに JVM チューニング パラメータを追加しない場合、つまり完全にデフォルトのオプションの場合、どの JDK バージョンを使用しても、新しい世代と古い世代のデフォルトの比率は 1:2 ではなくなります。

Eden、Survivor From、Survivor To のデフォルトの比率は 8:1:1 ではなくなりました。理由はゆっくり説明されます。

01 まずJDKのバージョンについてお話しましょう

JDK1.5より、公開バージョン番号はJDK5コマンド方式に変更され、開発バージョン番号のみJDK1.5コマンド方式を採用するようになりました。

現在、最新の JDK バージョンは 2021 年 3 月にリリースされた JDK16 です。この記事ではすべての JDK バージョンをカバーしますが、現在 JDK8 のシェアが最も高く、JDK8 は LTS バージョン (長期サポート) であるため、JDK8 がメインラインとなります。

JDK8 は 2014 年 3 月にリリースされ、JDK8 の最終サポート日は 2030 年 12 月と約束されています。

JDK8 の次の LTS バージョンは JDK11 で、2018 年 9 月にリリースされました。JDK11 の約束された最終サポート日は 2026 年 9 月で、JDK8 ほど長くはありません。

次の LTS バージョンは JDK17 で、2021 年 9 月にリリースされる予定です。JDK9 以降、JDK バージョンのリリースは厳密に時間ベースのモデルに変更され、新しいバージョンは 6 か月ごとにリリースされ、LTS バージョンは 3 年ごとにリリースされます。

02 GCコレクターについてお話しましょう

手順は次のとおりです。

① 最新バージョンのJDKでは、上記9つのGCコレクターに加え、JDK11で導入されたEpsilonコレクターも存在します。

つまり、現在、履歴には 10 個の GC コレクターがあり、Epsilon コレクターはガベージ コレクション作業を一切実行しません (No-Op ガベージ コレクター)。

たとえば、GC パフォーマンスの影響を排除することが期待され、プロセス実行ライフ サイクルが短いパフォーマンス テストなどの特殊なシナリオの場合です。したがって、それはこの記事の議論の範囲外です。

②ZGCとシェナンドーは同様の設計目標を持っており、どちらもG1の欠点を解決することを目的としています。唯一の違いは、ZGC は Oracle によって開始されたのに対し、Shenandoah は RedHat によって開始されたことです。そのため、公式の注目度には若干の違いがある可能性があります。

さらに、JDK16 までは、これら 2 つのコレクターはデフォルトのオプションとして G1 を置き換えていませんでした。これら 2 つのコレクターはスループットと応答時間の両方を考慮できることが公式に発表されていますが、各 JDK バージョンは継続的に最適化されており、まだ成熟には至っていません。

③JDK8の「JEP 173: Retire Some Rarely-Used GC Combinations」では、-XX:+UseParNewGCの組み合わせは廃止されました。詳細については、http://openjdk.java.net/jeps/173 を参照してください。

理由: あまり使用されない組み合わせです。

④ -XX:+UseConcMarkSweepGC の組み合わせの CMS コレクターは、JDK9 の「JEP 291: Concurrent Mark Sweep (CMS) ガベージ コレクターの非推奨」では使用が推奨されなくなりました。

そして、これは JDK14 の「JEP 363: Concurrent Mark Sweep (CMS) ガベージ コレクターの削除」で廃止されました。

詳細については、http://openjdk.java.net/jeps/291、http://openjdk.java.net/jeps/363 を参照してください。

理由は、G1 がデフォルトのコレクターになったためです。 CMS と同様に、G1 は応答時間を優先します。 G1 の使命は CMS を置き換えることです。

スペースが限られているため、この記事では各 GC コレクターの具体的な機能と原理については詳しく説明しません。

03 新しい世代と古い世代のデフォルトの比率を決定するパラメータはどれですか?

NewRatio、デフォルト値: 2。これは、新しい世代と古い世代のデフォルトの比率が 1:2 であることを意味します。

下の図に示すように、JDK8 での NewRatio のデフォルト値は 2 であるだけでなく、最新バージョンの JDK16 でも NewRatio のデフォルト値は 2 のままです。SurvivorRatio、デフォルト値: 8、効果は同じです。

NewRatio と SurvivorRatio はデフォルト値のままで問題ありませんが、実際には効果がない可能性があります。具体的な検証・分析プロセスについては、以下で説明します。

04検証分析

以下の検証および分析プロセスはすべて JDK8 に基づいています。

①プロセスを開始するときにJVMパラメータを追加しない

デフォルト: -XX:+UseParallelGC、Parallel Scavenge+Parallel Old GC コレクターの組み合わせ。

下の図に示すように、NewRatio=2、NewSize=42.0MB、OldSize=84.0MBとなり、1:2の比率を満たしています。

しかし、ヒープ使用量の詳細を見ると、Eden Space の容量は 306.5 MB であり、これは PS Old Generation の容量 130.5 MB よりも大きいことがわかります。

さらに、Eden、Survivor From、Survivor To の比率は明らかに 8:1:1 ではありません。なぜそうなるのでしょうか?

②他のGCコレクターパラメータを使用してみますか?

-XX:+UseSerialGC: Serial+Serial 古い GC コレクターの組み合わせ。

ヒープ使用量の詳細を見ると、追加の New Generation = Eden + 1 Survivor Space があります。

もうひとつの Survivor Space (From Space または To Space) を追加すると、ちょうど 42.0MB になり、OldSize との比率は 1:2 なので問題ありません。

さらに、Eden、Survivor From、Survivor To の比率は明らかに 8:1:1 です。

-XX:+UseConcMarkSweepGC: ParNew+CMS GC コレクターの組み合わせ。

ヒープ使用量の詳細を見ると、効果は基本的に -XX:+UseSerialGC と同じであり、問​​題はありません。

-XX:+UseG1GC: G1 コレクター。

ヒープ使用量の詳細を見ると、NewRatio マーカーで示されるデフォルトの比率 1:2 に準拠していません。さらに、「From Space」と「To Space」も消えてしまいました。これはなぜでしょうか?

その他の組み合わせ: 非推奨または削除なので、参照には使用されません。

③原因分析

(1) JDK 1.3以前では、コレクターのオプションは-XX:+UseSerialGCのみでした。当時、JVM の新世代と旧世代のデフォルトの比率は確かに 1:2 でした。

(2) -XX:+UseConcMarkSweepGCは、-XX:+UseSerialGCのマルチスレッドバージョンに似ており、コードフレームワークの再利用があるため、パフォーマンスは同じです。

(3) -XX:+UseSerialGC、-XX:+UseG1GC、-XX:+UseZGC、-XX:+UseShenandoahGCは従来のGCコードフレームワークを使用しないため、パフォーマンスが異なります。

(4)前の点を踏まえると、JDK7U4以前の-XX:+UseParallelGCの旧世代GCはSerial Oldであることに注目する価値がある。

実際、Serial Old のコード フレームワークは再利用されていません。 -XX:+UseParallelGC の旧世代の GC は PS MarkSweep と呼ばれます。その実装原理は Serial Old と非常に似ているため、公式のものも含め多くの資料では Serial Old を参照しています。

(5) UseAdaptiveSizePolicyパラメータは非常に重要です。このパラメータはデフォルトで有効になっており、最新バージョンの JDK16 まで有効なままになります。

このパラメータは、有効かどうかに関係なく、-XX:+UseSerialGC および -XX:+UseConcMarkSweepGC には影響しません。

このパラメータは、GC 適応調整戦略 (GC エルゴノミクス) に対応します。オンにすると、JVM はシステムの動作に応じて、新世代と旧世代の比率など、いくつかのパラメータを動的に調整します。

Eden、Survivor From、Survivor To の比率。スループット優先の目標を達成するために、大きなオブジェクトが古い世代に直接入るしきい値などを設定します。

④UseAdaptiveSizePolicyパラメータをオフにしてみてはいかがでしょうか?

有効化パラメータは -XX の後にプラス記号が付き、無効化パラメータは -XX の後にマイナス記号が付きます。プロセスを開始するときに、JVM パラメータ -XX:-UseAdaptiveSizePolicy を追加します。

GC コレクターは引き続きデフォルトを維持します: -XX:+UseSerialGC (Parallel Scavenge+Parallel Old の組み合わせ)。

ヒープ使用量の詳細を確認すると、すべてが正常であり、新しい世代と古い世代の比率は 1:2 です。 Eden、Survivor From、Survivor To の比率も 8:1:1 です。

⑤UseAdaptiveSizePolicyパラメータ関連ソースコード解析

ホットスポットのソース コードは http://hg.openjdk.java.net から取得します。

-XX:+UseParallelGC の新しい世代は psScavenge.cpp に実装され、古い世代は psOldGen.cpp に実装されています。どちらも hotspot\src\share\vm\gc_implementation\parallelScavenge ディレクトリにあります。

下図のように、UseAdaptiveSizePolicy がデフォルトでオンになっている場合、動的調整処理ロジックに入ります。

次の図は、動的調整処理ロジックに入った後のコアコード heap→resize_young_gen を示しています。

⑥最新の -XX:+UseZGC や -XX:+UseShenandoahGC はどうでしょうか?

G1 コレクターも世代別コレクション理論に従いますが、新しい世代と古い世代を区別せずに、連続した Java ヒープを同じサイズの領域に分割します。各地域は必要に応じて新世代空間または旧世代空間の役割を果たします。

G1 では新世代と旧世代が維持され、新世代では Eden と Survivor も区別されますが、Survivor では From と To が区別されなくなりました。

ZGC と ShenandoahGC に関しては、破壊活動はより徹底的です。彼らはもはや新世代と旧世代を区別しません。つまり、世代別回収は行われなくなり、デフォルト率の問題はもはや意味をなさなくなります。

05まとめ

①NewRatio、デフォルト値は2で、最新のJDK16バージョンでも永続的かつ真です。

結局のところ、最も長い歴史を持ち、多大な貢献をした -XX:+UseSerialGC は、非推奨になったり削除されたりしたことはありません。これはクライアント モードでは引き続きデフォルトのオプションです。

②JVM の新世代と旧世代のデフォルトの比率は、選択した GC コレクターに関係します。関連性があるだけでなく、新世代と旧世代の概念が存在するかどうかも決定します。

③ -XX:+UseParallelGC が -XX:+UseSerialGC に取って代わってデフォルトオプションとなったため、JVM 新世代と旧世代のデフォルト比率は 1:2 ではなくなり、現在最もシェアが高い JDK8 のように動的に比率を調整できるようになりました。

④ JDK9以降では、-XX:+UseParallelGCがデフォルトのオプションとして-XX:+UseG1GCに置き換えられます。

あるいは、将来的には -XX:+UseZGC または -XX:+UseShenandoahGC がデフォルトのオプションになる可能性があります (結局のところ、設計目標は G1 の欠点を解決することです)。

JVM の新世代と旧世代のデフォルトの比率は 1:2 ではなくなり、新世代と旧世代の概念さえも存在しなくなる可能性があります。

そのため、JVM の新世代と旧世代のデフォルトの比率は 1:2 であるという誤った認識が 10 年間続いてきました。

面接官と求職者は、あまり精査しなくても常によく理解しています。この記事が業界内の誤解の一部を変えることができれば幸いです。

さらに、「Java 仮想マシンの徹底理解」は業界では JVM Sunflower バイブルや上級 JVM 教科書とみなされていますが、本書の多くの議論はタイムリーに更新されておらず、読者を誤解させる可能性があります。

本を盲目的に信じるよりは、本を持たないほうがましだ。面接官を騙すために暗記した面接の質問を使って求職者を騙すのは、単なる不良行為です。

著者: バンブルビー

紹介: Huawei や Tencent などの大手インターネット企業で勤務した経験があります。 2018年5月、ユニコーン企業Akulakuに技術管理職として入社。分割払いや金融融資などの基幹システムのアーキテクチャ設計において豊富な実務経験を持つ。 Redis と JVM に精通しており、基礎となる原理を重視し、高度な使用方法、プロトコル、ソースコードなどを深く研究しています。また、独自のチーム管理哲学を持ち、異なるアプローチを採用し、R&D の品質と効率に重点を置いており、会社のために多くの若くて有望な人材を育成し、さまざまな賞を何度も受賞しています。

編集者:タオ・ジアロン

論文募集: 論文の投稿や取材に興味のある技術者の方は、編集者のWeChatアカウントgordonlonglongを追加してください。

[51CTO オリジナル記事、パートナーサイトに転載する場合は、元の著者とソースを 51CTO.com として明記してください]

<<:  国内ブランドは天一クラウドを採用し、デジタル変革を推進するために協力している

>>:  テンセントクラウドがTecho Hub全国技術ツアーイベントを開始、コンピューティング技術のネタバレを事前に最初にチェック

推薦する

ウェブマスターは広告提携をどのように選択すればよいでしょうか?

ウェブマスターが最も気にするのは、ウェブサイトをいかに収益性の高いものにするかということです。ウェブ...

フォグコンピューティングについて知っておくべきことすべて

モノのインターネットの台頭により、これらのデバイスによって生成される膨大な量のデータをサポートできる...

クッキーが SEO ランキングに影響を与えるのはなぜですか?

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますクッキーが...

Redis に基づいて分散ロックを実装するにはどうすればいいですか?

[[432396]] 1. 分散ロックが必要なのはなぜですか?分散ロックについて話す前に、なぜ分散ロ...

Bステーションブランドのマーケティング戦略!

Bilibiliは今でもZ世代と伝統的な言語でコミュニケーションを取っているのでしょうか? Z世代が...

Weiboマーケティングトラフィック転換方法とチャネル

ショートビデオ、セルフメディア、インフルエンサーのためのワンストップサービスWeibo は、Weix...

仮想化の「厄介な」問題を解決する方法:「クラウド」データセンター

クラウド コンピューティングが爆発的に普及しているこの時代では、仮想化テクノロジがますます広く使用さ...

ショックホスティングはどうですか?ダラスデータセンターのVPSの簡単なテスト

shockhosting は、ダラス データ センターで VPS および専用サーバー サービスを提供...

Serverdragon デュアル IP 低コスト年間 VPS (年間支払いはわずか 8 ドル)

serverdragon は、フロリダとデンバーで特別な VPS、デュアル IP、オプションのデータ...

どのようなウェブサイトが Baidu で上位にランクされるのでしょうか?

2018年最もホットなプロジェクト:テレマーケティングロボットがあなたの参加を待っていますウェブサイ...

ダブルイレブンに備える: 最高のイベントを企画するのに役立つ 4 つのケーススタディ

月収10万元の起業の夢を実現するミニプログラム起業支援プラン活動は一般的ですが、良い活動はまれです。...

5Gはエッジコンピューティングの強力な原動力となる

エッジ コンピューティングは、デジタル世界で最もエキサイティングな新しいコンセプトの 1 つです。エ...

ntup: ウクライナの無制限トラフィックサーバー、1Gbps、月額料金は 26 ドルから

ntup はウクライナの会社で、ウクライナのドニプロに独自のデータセンターを持っています。現在の主な...

Baidu プロモーションの「アカウント品質評価」について

Baidu Promotion のアカウント品質スコアが表示された正確な時間についてはよく分かりませ...

クラウドネイティブで MySQL の高可用性を実現するにはどうすればよいでしょうか?

現在人気のリレーショナル データベース (RDS) である MySQL は、クラウド ネイティブの波...