13

ドキュメント「Java HotSpot™ 仮想マシンのメモリ管理」の 6 ページには、次の段落が含まれています。

若い世代のコレクションは比較的頻繁に発生し、効率的かつ高速です。これは、通常、若い世代のスペースが小さく、参照されなくなった多くのオブジェクトが含まれている可能性が高いためです。

いくつかの若い世代のコレクションを生き残ったオブジェクトは、最終的には古い世代に昇格または保有されます。図 1 を参照してください。この世代は通常、若い世代よりも大きく、その占有率はよりゆっくりと成長します。その結果、古い世代のコレクションは頻繁ではありませんが、完了するまでにかなりの時間がかかります

上記のステートメントで「頻繁に」と「まれに」の意味を誰か定義してもらえませんか? 私たちはマイクロ秒、ミリ秒、分、日を話しているのでしょうか?

4

5 に答える 5

16

これには明確な答えを出すことはできません。実際には、プラットフォーム (JVM のバージョン、設定など)、アプリケーション、ワークロードなど、多くの要因に依存します。

極端な例として、アプリケーションがガベージ コレクターをトリガーしない可能性があります。何もせずにただそこに座っているか、JVM の初期化とアプリケーションの起動後にオブジェクトが作成されない非常に長い計算を実行する可能性があります。

反対に、理論的には、1 つのガベージ コレクションが終了し、別のガベージ コレクションが数ナノ秒以内に開始される可能性があります。たとえば、アプリケーションが完全なヒープで停止する最終段階にある場合、または非常に大きな配列を割り当てている場合に、これが発生する可能性があります。

そう:

私たちはマイクロ秒、ミリ秒、分、日を話しているのでしょうか?

上記のすべての可能性がありますが、実際に観察した場合、最初の 2 つは間違いなく厄介です。

正常に動作するアプリケーションでは、GC をあまり頻繁に実行しないでください。アプリケーションが若い領域のコレクションを 1 秒間に 1 回または 2 回以上トリガーしている場合、パフォーマンスの問題が発生する可能性があります。また、「完全な」コレクションが頻繁すぎると、その影響が大きくなるため、さらに悪化します。ただし、設計/実装が不十分なアプリケーションがこのように動作することは確かにもっともらしいです。


また、GC の実行間隔が常に意味のあるものではないという問題もあります。たとえば、一部の HotSpot GC では、通常のアプリケーション スレッドと同時に実行される GC スレッドを実際に持っています。十分な数のコア、十分な RAM、および十分なメモリ バス帯域幅があれば、コンカレント GC を常に実行しても、アプリケーションのパフォーマンスに大きな影響を与えることはありません

用語に関する注意:

  • 厳密に言えば、並行 GC とは、アプリケーション スレッドと同時に GC を実行できるものです。
  • 厳密に言えば、並列 GC とは、GC 自体が複数のスレッドを使用するものです。
  • GC は、並列でなくても並列にすることができ、その逆も可能です。
于 2012-09-26T11:09:21.570 に答える
4

その相対的な用語。若いコレクションは、1 秒間に何回も、最大で数時間かかる可能性があります。古い世代のコレクションは、数秒ごとから毎日まで可能です。ほとんどのシステムでは、古いコレクションよりも若いコレクションの方がはるかに多いと予想する必要があります。

何日もかかる可能性はほとんどありません。OutOfMemoryError: GC Overhead ExceededGC が頻繁に発生する場合、たとえば << 100 ミリ秒間隔で発生すると、JVM が発生を防止するため、a が得られます。

于 2012-09-26T09:56:41.167 に答える
0

TL DL: 「頻繁」と「まれ」は、メモリ割り当て率とヒープ サイズに依存する相対的な用語です。正確な答えが必要な場合は、特定のアプリケーションについて自分で測定する必要があります。

アプリに 2 つのモードがあるとします。モード 1 はメモリを割り当てて計算を行い、モード 2 はアイドル状態になります。

モード 1 の割り当てが使用可能なヒープよりも小さい場合、終了するまで gc を実行する必要はありません。RAM の使用量が少なすぎて、コレクションなしでモード 1 の 2 回目のラウンドを実行できたのかもしれません。ただし、最終的に空きヒープが不足し、jvm は「まれな」コレクションを実行します。

ただし、モード 1 の割り当てが若い世代のヒープのかなりの割合であるか、それよりも大きい場合、コレクションはより「頻繁に」発生します。若い世代のコレクション中に、生き残った割り当て (モード 1 操作全体でデータが必要であると想像してください) は古い世代に昇格され、若い世代により多くの余地が与えられます。若い世代の割り当てと収集が継続できるようになりました。最終的に古い世代のヒープが不足するため、「まれに」収集する必要があります。

では、頻度はどれくらいですか?これは、割り当て率とヒープ サイズによって異なります。jvm がヒープ制限に頻繁にぶつかる場合は、頻繁に収集されます。十分なヒープ (100GB としましょう) がある場合、jvm は長い間収集する必要はありません。欠点は、最終的にコレクションを実行するときに、100GB を解放するのに長い時間がかかり、jvm が数秒 (または数分!) 停止する可能性があることです。現在の JVM はそれよりもスマートで、コレクションを強制的に実行することがあります (モード 2 が望ましい)。また、並列コレクターを使用すると、必要に応じて常に発生する可能性があります。

最終的に、頻度はタスクとヒープに依存し、さまざまな vm パラメータがどのように設定されているかにも依存します。正確な答えが必要な場合は、特定のアプリケーションについて自分で測定する必要があります。

于 2014-10-29T23:05:29.390 に答える
0

そのままでは、「頻繁」、「まれ」という用語は相対的です。そして、実際には、タイミングは固定されていません。問題のシステムによって異なります。それは次のような多くのことに依存します:

  • ヒープのさまざまな部分 (young、old gen、perm gen) のヒープ サイズと設定
  • アプリケーションのメモリ動作。作成されるオブジェクトの数と速度は? それらのオブジェクトが参照されている期間などは?

あなたのアプリケーションが巨大なメモリを食べる場合、gc はあたかもその寿命のために実行されているかのように実行されます。アプリケーションが大量のメモリを必要としない場合、gc はメモリがどれだけいっぱいかによって決定される間隔で実行されます。

于 2012-09-26T10:00:30.950 に答える
-2

仕様には「比較的頻繁に」と記載されているため (Young 世代に関しては) まれであるため、マイクロ秒、ミリ秒、分、または日などの絶対単位で頻度を見積もることはできません。

于 2012-09-26T09:56:05.977 に答える