2017-08-09 1 views
-6

C#でヒープを使った完全な作業を理解したい。スタックとヒープの仕組みを理解していますが、可能であればヒープの最適化の説明は見つかりませんでした。C#でのヒープのデフラグメンテーション?

GCがヒープ上でメモリブロックを割り当てたり割り当てを解除したりするときに、断片化に関する問題についてたくさん読んでいます。

誰かが私に説明したり、この懸念とヒープ(メモリ)の最適化に関する良い記事を書いてくれれば。

+0

[CLR via C#](https://blogs.msdn.microsoft.com/microsoft_press/2012/11/29/new-book-clr-via-c-fourth-edition/)から開始してください。 –

答えて

0

ヒープの仕組みを知っていれば、いくつかの種類のヒープがあることを知っていると思います。私の答えはここを参照してください - Stack vs. Heap in .NET

私はその答えで言及しているので、2ラージオブジェクトヒープ(LOH)とGCヒープ(Ephemeralヒープとも呼ばれます)です。

通常、.NETのヒープフラグメンテーションについて心配する必要はありません。 GC for .NETは、マーク、スイープ、コンパクトという3つのステップで動作します。マーク - すべてのルーテッド参照をスキャンし、であるもののリストを作成します。これらはガベージコレクションに適格ではなく、触れられません。スウィープ - リストにないアイテムのメモリをクリアし、マークされたアイテムの「マークされたビット」をクリアします。コンパクト - 残りのルートオブジェクトが連続したブロックになるように、メモリを移動します。 Compactフェーズの注意点の1つは、LOHが少なくとも.NET 4.6.2の最新バージョンで圧縮されていないことです。これは、すべてのメモリを連続したブロックに移動するのにかかるパフォーマンスの理由と時間のために、CLR GCチームが作成した設計上の決定でした。 .NET 1.0以来、多くのパフォーマンスの改善が行われています。そのため、GCは従来の獣ではありません。いずれにしても、Gen 0、1、および2のヒープは、が圧縮されています。したがって、そこの断片化を心配する必要はありません。ほとんどの場合、LOHは実装するアルゴリズムにフラグメンテーションの問題がなくても存続します。あなたがLOH上でフラグメンテーションを得ることができるケースがあります。これは、割り当てパターンの悪さや頻繁なFull GCコレクションなどのいくつかによって引き起こされる可能性があります。これは、割り当てパターンを改善し、可能な限り密接に(プログラムで)大量のメモリを割り当て、オブジェクトプーリングによって対処できます。

    :.NET 4.5.1のよう

    は、私は強く2つの理由で、それはあなたのアプリケーションのための巨大なパフォーマンスのヒットであることを理由それに対して推薦するものの、手動でLOHを圧縮する方法があります
  1. これは時間がかかります。
  2. あなたのアプリのライフタイムにわたってGCが収集した割り当てパターンアルゴリズムをクリアします。あなたのアプリが実行されている間、GCは実際にあなたのアプリがメモリをどのように割り当てるかを知ることによって、自分自身を調整します。そのため、アプリが実行される時間が長くなるほど(特定のポイントまで)効率的になります。 GC.Collect()(またはそのオーバーロード)を実行すると、GCが学習したすべてのデータがクリアされるため、最初からやり直す必要があります。コンパクト、GCマーク、スイープについて

情報(、私はそれに対してお勧めします再び)https://blogs.msdn.microsoft.com/mariohewardt/2013/06/26/no-more-memory-fragmentation-on-the-net-large-object-heap/ - https://blogs.msdn.microsoft.com/abhinaba/2009/01/30/back-to-basics-mark-and-sweep-garbage-collection/

情報LOH割り当てアルゴリズムについて:手動でここにLOHを圧縮する方法の詳細を読むことができ https://www.red-gate.com/simple-talk/dotnet/net-framework/the-dangers-of-the-large-object-heap/