Javaと.Netガベージコレクタの主な違いを知っている人はいますか?ウェブ検索ではあまり明らかにされておらず、テストで出てきた質問でした。
違いは、言語自体ではなく、CLR(.Net)GCとJVMGCの違いです。どちらも変更される可能性があり、プログラムの正確性に影響を与えることなくこれを変更できるように、動作の仕様は緩いです。
Java(および他のgcベースのプラットフォーム)の進化からの教訓を基に設計された.Netに主に起因するいくつかの歴史的な違いがあります。以下では、.Netが最初から機能が含まれているため、ある程度優れていますが、それは単に後から来た結果です。
注目すべき公に目に見える違いは、MS GCがその世代の性質を(GC apiを介して)公開することです。これは、ほとんどのプログラムが示す動作に基づいて実行する明らかなアプローチであるため、しばらくの間当てはまる可能性があります。ほとんどの割り当ては非常に短命。
この機能はすぐに追加されましたが、初期のJVMには世代別のガベージコレクターがありませんでした。によって実装された第一世代のコレクター 太陽オラクルなどはマークアンドスイープの傾向がありました。マークスイープコンパクトアプローチは、追加のコピーオーバーヘッドを正当化するはるかに優れたメモリ局所性につながることがわかりました。 CLRランタイムは、この動作でデビューしました。
の違い 太陽OracleとMicrosoftのGC実装「ethos」は構成可能性の1つです。
太陽には、GCのさまざまな側面を調整したり、GCを異なるモードに切り替えたりするための(コマンドラインで)膨大な数のオプションが用意されています。多くのオプションは-Xまたは-XXであり、さまざまなバージョンまたはベンダー間でサポートが不足していることを示します。対照的に、CLRは構成可能性をほとんど提供しません。あなたの唯一の現実的な選択肢は、スループットとレイテンシをそれぞれ最適化するサーバーまたはクライアントのコレクターを使用することです。
GC戦略の活発な研究が両社(およびオープンソースの実装)で進行中です。最新のGC実装で使用されている現在のアプローチは、スレッドごとのeden領域です(局所性を改善し、edenコレクションが完全な一時停止を引き起こさないようにする)。エデン世代への特定の割り当ての配置を回避しようとする事前保有期間アプローチとして。
これは、ShuggyCoUkの優れた答えに追加するだけです。 .NET GCは、ラージオブジェクトヒープ(LOH)と呼ばれるものも使用します。 CLRは、LOHに多数のオブジェクトを事前に割り当て、少なくとも85000バイトのユーザーが割り当てたすべてのオブジェクトもLOHに割り当てられます。さらに、double[]
いくつかの内部最適化により、1000要素以上がLOHにも割り当てられます。
LOHは、さまざまな方法で世代別ヒープとは異なる方法で処理されます。
malloc
がCランタイムで処理されるのと同じように、フリーリストを介して行われますが、世代ヒープからの割り当ては、基本的に、世代0でポインターを移動するだけで行われます。JVMに似たようなものがあるかどうかはわかりませんが、.NETでのメモリの処理方法に関する重要な情報であるため、役立つことを願っています。
正しく思い出せば、JVMはCLRのように、割り当て解除されたメモリをオペレーティングシステムに解放しません。
Java 5では、GCアルゴリズムに多くの変更が加えられました。
私はC#の専門家ではありませんが、これら2つの記事は、どちらも単純なマークとスイープから新しい世代のモデルへと進化したことを示唆しています。
http://Java.Sun.com/docs/hotspot/gc5.0/gc_tuning_5.htmlhttp://www.csharphelp.com/archives2/archive297.html