JVM GCはマイナーGCで収集できるため、短命オブジェクトが大好きです。しかし、なぜJVM GCは不変オブジェクトを好んでいますか?JVMのGCで変更できないオブジェクトがなぜ好きですか?
編集: チャーリー・ハントは、GCが彼のpresentationの不変オブジェクトを愛していると言います。
おかげlink..foundため
JVM GCはマイナーGCで収集できるため、短命オブジェクトが大好きです。しかし、なぜJVM GCは不変オブジェクトを好んでいますか?JVMのGCで変更できないオブジェクトがなぜ好きですか?
編集: チャーリー・ハントは、GCが彼のpresentationの不変オブジェクトを愛していると言います。
おかげlink..foundため
オブジェクトにgen0オブジェクトへの参照が含まれていないことをGCが認識できる場合は、gen0コレクションを実行するときに無視できます。同様に、オブジェクトにgen0またはgen1オブジェクトへの参照が含まれていない場合は、gen1コレクションを実行するときに無視されることがあります。コレクション中に多くのオブジェクトが無視されると、そのコレクションはより速くなります。
オブジェクトがgen0 GCに残っている場合、参照を保持していた任意のgen0オブジェクトがgen1に昇格されていることを確認できます。同様に、gen0参照を含まないオブジェクトがgen1 GCで存続する場合、それに含まれるgen1参照はgen2に昇格されています。したがって、あるオブジェクトがgen0コレクション中に検査されると、が変更されない限り、次のgen1コレクション、まで再度検査する必要はありません。同様に、gen1コレクション中に検査されるオブジェクトは、が変更されない限り、次のgen2コレクションまで検査する必要はありません。
オブジェクトが変更されているかどうかを知るのは難しい問題ですが、オブジェクトが存在しない場合は、GCにとって非常に有利です。
ありがとう、@スーパーマップ。私は質問があります:a)「無視する」とは、オブジェクトをさらに追跡しないことを意味しますか? b)gen0、gen1、gen2とは何ですか?若い世代と古い世代を意味しますか? c)GCはオブジェクトが変更されたかどうかを知っていますか? – Jacky
@ジャッキー:「無視する」とは、私が実際に「さらにトレースしない」ことを意味します。私は主に.netを使用して0-2の世代番号を付けます。私は、Javaの実装には「若い」世代と「古い世代」という1つ以上の世代があると思いますが、詳細はわかりません。 GCが「マーク」フェーズで世代を利用するためには、世代ごとに最後のGC以降にどのオブジェクトが変更されているのかを知る必要があります。そのためのメカニズムはかなり複雑です。参照が可能になる前に内容が指定されることを要求する不変オブジェクトを宣言する特別な手段があった場合... – supercat
...このようなオブジェクトは、現在の実行スコープから渡されたかどうかを追跡するメカニズムを持つ必要はない彼らは変更された(彼らは単に変更されないので)。変更可能なオブジェクトへの変更を追跡するのに十分なほど洗練された仮想メモリメカニズムをサポートしているシステムでは(そしてさらにはるかに制限されたVMメカニズムを持つ多くの場合でも)、同じメカニズムを使用して、 「不正な」コードによって。 – supercat
おかげで、それの素敵なプレゼンテーションから:)
:GCは小さな不変オブジェクトと短命オブジェクトを愛しています。
編集:
小さなオブジェクトが短いメモリフットプリントを持って収集した後、彼らは再利用を取得した後、彼らはより大きなメモリホールを残すように、メモリ圧縮が大きなオブジェクトの遅い(メモリ圧縮に多くのオーバーヘッドがあることないことを意味しますGCによる)。また、短命のオブジェクトは、小さなGCサイクルで収集されるので、良いものです。
大きなオブジェクトは、マイナーgcの間に生存エリアに収まらない場合、古い世代に直接プロモートされる可能性があります。もっと悪いケースでは、若い世代の自由空間に収まらない場合、それが作成されたときに古い世代に直接昇格される可能性があります。 – Jacky
不変オブジェクトには多くの利点があります。 GCはトレース中にすべての不変オブジェクトを簡単に見つけることができると思います。私はそれが彼らの世話をするためにオーバーヘッドをどのように減らすことができるかを理解していません。私は、ハントがそれを述べた理由がいくつかあると信じています。 – Jacky
ええ、不変なオブジェクトを小さくすることは、最適なパフォーマンスを得るには理想的ですが、GCは不変なオブジェクトだけを好むことを強調しません。 –
Brian Goetzの回答articleが見つかりました。
ほとんどの場合、ホルダーオブジェクトが異なるオブジェクトを参照するように更新されると、新しい参照先は若いオブジェクトになります。 setValue()を呼び出してMutableHolderを更新すると、古いオブジェクトが新しいものを参照する状況が発生しています。一方、代わりに新しいImmutableHolderオブジェクトを作成することで、若いオブジェクトは古いオブジェクトを参照しています。ほとんどのオブジェクトが古いオブジェクトを指している後者の状況は、世代別のガベージコレクタでははるかに穏やかです。古い世代のMutableHolderが変更された場合、MutableHolderを含むカード上のすべてのオブジェクトは、次のマイナーコレクションでold-to-young参照をスキャンする必要があります。長命のコンテナオブジェクトに対する変更可能な参照の使用は、コレクション時に古いものから若いものへの参照を追跡する作業を増加させます。
不変のヒープがカードテーブルを必要としないという条件で、注目すべきGCフレームワークに可変オブジェクトと不変オブジェクトの別々のヒープがあるのだろうかと思います。確かに、コンパクトなフレームワークをしようとすると、gen1/gen2の可変オブジェクトがすべてのコレクションでスキャンされた(しかし、移動されなかった)が、不変のオブジェクトはスキャンされなかった場合、カードテーブルなしでまともなパフォーマンスを得ることができると思います。 – supercat
JVM GCは不変オブジェクトを愛していますか? – lichengwu
ありがとう、@lichengwu、私はソースを追加して質問を編集しました。 – Jacky