ジェネレーションとラージオブジェクトヒープについて読みました。しかし、私はまだ大きなオブジェクトヒープを持つことの重要性(または利点)が何であるか理解できませんか?
ラージオブジェクトを格納するためにCLRがジェネレーション2(Gen0およびGen1のしきい値が小さいことを考慮すると)に依存している場合、(パフォーマンスまたはメモリの観点から)何が問題になっている可能性がありますか?
ジェネレーションとラージオブジェクトヒープについて読みました。しかし、私はまだ大きなオブジェクトヒープを持つことの重要性(または利点)が何であるか理解できませんか?
ラージオブジェクトを格納するためにCLRがジェネレーション2(Gen0およびGen1のしきい値が小さいことを考慮すると)に依存している場合、(パフォーマンスまたはメモリの観点から)何が問題になっている可能性がありますか?
回答:
ガベージコレクションは、参照されていないオブジェクトを削除するだけでなく、ヒープも圧縮します。これは非常に重要な最適化です。メモリの使用効率を上げるだけでなく(未使用のホールをなくす)、CPUキャッシュをより効率的にします。キャッシュは最近のプロセッサでは非常に重要であり、メモリバスよりもはるかに高速です。
バイトをコピーするだけで圧縮が行われます。ただし、これには時間がかかります。オブジェクトが大きいほど、オブジェクトをコピーするコストがCPUキャッシュ使用率の改善の可能性を上回る可能性が高くなります。
そこで、彼らは損益分岐点を決定するために一連のベンチマークを実行しました。そして、コピーがパフォーマンスを改善しないカットオフポイントとして85,000バイトに到達しました。doubleの配列の特別な例外を除いて、配列に1000を超える要素がある場合、それらは「大きい」と見なされます。これは32ビットコードの別の最適化です。ラージオブジェクトヒープアロケーターには、8にアライメントされたアドレスにメモリを割り当てるという特別なプロパティがあります。これは、4にのみアライメントを割り当てる通常の世代別アロケーターとは異なり、そのアライメントはdoubleの大きな問題です、誤って配置されたdoubleの読み取りまたは書き込みは非常に高価です。奇妙なことに、まばらなMicrosoftの情報では、長い配列については言及されていません。
Fwiw、ラージオブジェクトヒープが圧縮されないことに多くのプログラマーが悩んでいます。これは、利用可能なアドレス空間全体の半分以上を消費するプログラムを書いたときに必ず発生します。続いて、メモリプロファイラーのようなツールを使用して、未使用の仮想メモリがまだたくさん残っているにもかかわらず、プログラムが攻撃された理由を調べました。このようなツールは、LOHの穴、以前は大きなオブジェクトが存在していたがガベージコレクションされていた未使用のメモリチャンクを示します。これはLOHの必然的な価格です。この穴は、サイズが同じか小さいオブジェクトの割り当てによってのみ再利用できます。実際の問題は、プログラムがいつでもすべての仮想メモリを消費できるようにする必要があることを想定しています。
64ビットオペレーティングシステムでコードを実行するだけで完全に解消される問題。64ビットプロセスには、8テラバイトの仮想メモリアドレス空間があり、32ビットプロセスより3桁大きくなります。あなただけの穴を使い果たすことはできません。
要するに、LOHはコードの実行をより効率的にします。使用可能な仮想メモリアドレス空間を使用すると、効率が低下します。
UPDATE、.NET 4.5.1はLOH、GCSettings.LargeObjectHeapCompactionModeプロパティの圧縮をサポートするようになりました。結果に注意してください。
小さいオブジェクトヒープ(SOH)と大きいオブジェクトヒープ(LOH)の本質的な違いは、この記事で説明されているように、LOHは収集されないが、SOHのメモリは収集時に圧縮されることです。大きなオブジェクトを圧縮すると、コストがかかります。記事の例と同様に、メモリ内の1バイトの移動には2サイクルが必要であり、2GHzコンピュータで8MBオブジェクトを圧縮するには8msが必要であり、これは大きなコストです。ラージオブジェクト(ほとんどの場合は配列)は実際には非常に一般的であると考えると、Microsoftがラージオブジェクトをメモリに固定してLOHを提案するのはそのためだと思います。
ところで、この投稿によると、LOHは通常、メモリフラグメントの問題を生成しません。
プリンシパルは、プロセスが多数の短命のラージオブジェクトを作成する可能性が低い(そしておそらく非常に悪い設計)であるため、CLRはラージオブジェクトを別のヒープに割り当て、その上で通常のヒープとは異なるスケジュールでGCを実行します。http://msdn.microsoft.com/en-us/magazine/cc534993.aspx