8

ガベージ コレクターがどのように機能するかを確認するために、非常に単純なコードを実行しました。

String a = null;
while ( true ) {
  a = new String(" no... ");
}

ParallelGC を使用しています。GC の結果を出力しました。これが最初の (マイナーな) GC です。

[GC [PSYoungGen: 16448K->1616K(19136K)] 16448K->1624K(62848K), 0.0022134 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]

youngGen はダウンしました14880K が、fullHeap はちょうどダウンしました14872K

これは、8k が在職世代に移行したことを意味しますか? 私の理解では、GC はクラス 'a' のインスタンス化されたものと呼ばれた可能性があり、生きているとマークされ、在職世代に移動されたに違いありません。この理解は正しいでしょうか?また、これは「浮遊ゴミ」ですか?時間の経過とともに、Tenure 世代がいっぱいになり、fullGC が必要になりますが、時間がかかります。

また、この特定のケースでは、マイナー コレクション全体が収集され、理想的には何もテニュア ジェネレーションに移行されるべきではありませんか? これらはすべて短命のオブジェクトです。

4

2 に答える 2

2

GC の進行中に String のインスタンスが 1 つ (while ループ内の強力な参照) 生き残っているため、1 つが生き残り、8k になります。

この場合、String ref フローティング ガベージとは呼びません。フローティング ガベージとは、GC がオブジェクトをチェックしたときにオブジェクトを GC する準備ができていなかったが、GC が終了するまでには準備ができていた場合です。その一例でしょう。

Thread1:    Person p = new Person("sammy")

    Thread2:    gc runs and sees that the Person instance is reachable through p.

Thread1:    p = null; // This Person instance is now unreachable.

    Thread2:    GC finishes. The person instance could have been collected but was reachable at the time the collector checked it.
于 2013-07-15T06:28:55.877 に答える
0

あなたの測定は正確ではないと思います。

まず、GC が発生すると、Eden が消去され、生き残ったオブジェクトが Survivor スペースに移動します。したがって、あなたの場合、これは YoungGen が 16448K から 1616K になる理由を説明しています。これらの 1616K は生存者の占有です。

一方、GC 後の総ヒープ占有率は 1624K であり、古い世代には実際に 8K のデータが含まれていることを意味します。

「フローティング ガベージ」という用語は、新しく死んだオブジェクトがコレクターによってキャッチされない CMS コレクションを指します。ParallelGC には適用されません。

テスト ケースに関しては、String オブジェクトが古い世代になることはありません。それらはせいぜい 1 GC サイクルで生き残り、サバイバー スペースに行き、その後回収されます。

それが役立つことを願っています!

于 2013-07-15T12:51:02.720 に答える