6

C# で長い TCP 接続ソケット サーバーを作成しました。サーバーのメモリでスパイクが発生します。dotNet Memory Profiler (ツール) を使用して、メモリ リークが発生している場所を検出しました。メモリ プロファイラは、プライベート ヒープが巨大であることを示しており、メモリは次のようになっています (数値は実際のものではありません。GC0 と GC2 のホールは非常に巨大で、データ サイズは正常です)。

  Managed heaps - 1,500,000KB 
          Normal heap - 1400,000KB 
              Generation #0 - 600,000KB 
                  Data - 100,000KB 
                  "Holes" - 500,000KB 
              Generation #1 - xxKB 
                  Data - 0KB 
                  "Holes" - xKB 
              Generation #2 - xxxxxxxxxxxxxKB 
                  Data - 100,000KB 
                  "Holes" - 700,000KB 
          Large heap - 131072KB 
              Large heap - 83KB 
              Overhead/unused - 130989KB 
          Overhead - 0KB

しかし、GCホールとは?dotNet Memory Profiler のドキュメントは、「穴」を定義しています。

「ホール」は、割り当てられた 2 つのインスタンス間で使用されていないメモリを表します。固定されたインスタンスまたはガベージ コレクターの最適化により、ヒープが完全に圧縮されていない場合、「穴」が表示されます。

私が知りたいのは:

  1. 割り当てられた 2 つのインスタンスの間に「穴」が現れるのは、次のうちどれですか?
  2. どのようなインスタンスが固定されていますか?
  3. ヒープを圧縮する方法は?

誰かが説明してくれることを願っています。

4

1 に答える 1

6

固定されたオブジェクトは、メモリ内での移動が許可されていないオブジェクトです。これは、メモリ内のある構造体へのポインタを渡す必要があるアンマネージ コードで作業する場合によく必要になります。一部のアンマネージ コードにその構造体へのポインターを指定した場合、それを移動すると、そのアンマネージ コードは正しい構造体を指しなくなり、予期しない動作につながります。

解決策は、そのオブジェクトを「固定」して、移動してはならないことを GC に伝えることです。

ヒープを明示的に圧縮することはできません。GC は、完全または部分的な収集 ( LOHを除く) を実行するときにこれ自体を圧縮する必要があります。ただし、多くのオブジェクトを固定すると、これをうまく管理することが難しくなります。GC の詳細については、ガベージ コレクターの基本とパフォーマンスのヒントを参照してください。

于 2012-10-15T12:59:30.777 に答える